2014. 2. 13. 10:22

Tip 정리

<윈도우 캡션 깜박이게 하기>

//---------------------------------------------------------
BOOL FlashWindow(
   HWND hWnd,   // 폼의 Handle속성을 지정
   BOOL bInvert   // 윈도우즈 95에서는 이 변수값을 무시하며,
   // True로 지정된 경우 타이틀바가 활성/비활성 상태가 토글된다
);
//---------------------------------------------------------

procedure TForm1.FormActivate(Sender: TObject);
begin
   Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   FlashWindow(Form1.Handle, True);
end;

 

<윈도우 디렉토리 알아내기>

//---------------------------------------------------------
UNIT GetWindowDirectory(
   LPTSTR lpBuffer, // 시스템 디렉토리를 저장할 버퍼의 포인터
   UINT uSize          // 디렉토리 버퍼의 크기
);
//----------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
   Windir : array[0..30] of char;
begin
   GetWindowsDirectory(Windir,sizeof(windir));
   Label1.Caption := Windir;
end;
 


<비퍼(beeper) ON/OFF 시키기>

//----------------------------------------------------
BOOL SystemParametersInfo(
   UINT uiAction,    // 조회하거나 변경할 시스템 파라미터변수
   UINT uiParam,    // 시스템 파라미터 변수에 따라 지정
   PVOID pvParam, // 시스템 파라미터 변수에 따라 지정
   UINT fWinini        // 시스템 파라미터 변수의 내용이 변경될 경우
                            // 사용자프로파일의 변경여부를 지정
);

BOOL MessageBeep(
   UINT uType
);
//-----------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
   SystemParametersInfo(SPI_SETBEEP, 1, Pchar(0), 0); // Beeper ON
   Label1.Caption := 'Beep On';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   SystemParametersInfo(SPI_SETBEEP, 0, Pchar(0), 0); //Beeper OFF
   Label1.Caption := 'Beep Off';

end;

procedure TForm1.Button3Click(Sender: TObject);
begin
   MessageBeep(MB_OK);
end;

 

<시스템 가동방법 알아내기>

//----------------------------------------------------
int GetSystemMetrics(
   int nIndex;    // 시스템에서 사용하는 정보에대한 변수값
);
//----------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
   boot : integer;

begin
   boot := GetSystemMetrics(SM_CLEANBOOT);
   case boot of
      0 : Label1.Caption := 'Normal Boot';
      1 : Label1.Caption := 'Fail-safe Boot';
      2 : Label1.Caption := 'Fail-safe with Network Boot';
   end;
end;

 

<마우스버튼 역할 바꾸기>

//----------------------------------------------------
BOOL SystemParametersInfo(
   UINT uiAction,          // 조회하거나 변경할 시스템 파라미터변수
   UINT uiParam,          // 시스템 파라미터 변수에 따라 지정
   PVOID pvParam,       // 시스템 파라미터 변수에 따라 지정
   UINT fWinini             // 시스템 파라미터 변수의 내용이 변경될 경우
                                 // 사용자 프로파일의 변경여부를 지정
);

BOOL MessageBeep(
   UINT uType
);
//------------------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
begin
   SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, 1, PChar(0), 0);
   Label1.Caption := 'Left : Popup Right : Pointing and Execute';
end;

procedure TForm1.Button2Click(Sender : TObject);
begin
   SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, 0, PChar(0), 0);
   Label1.Caption := 'Left : Pointing and Execute Right : Popup';
end;

 

<스크린세이버 ON/OFF시키기>

//-----------------------------------------------------
BOOL SystemParametersInfo(
   UINT uiAction,     // 조회하거나 변경할 시스템 파라미터변수
   UINT uiParam,     // 시스템 파라미터 변수에 따라 지정
   PVOID pvParam,  // 시스템 파라미터 변수에 따라 지정
   UINT fWinini        // 시스템 파라미터 변수의 내용이 변경될 경우
//사용자프로파일의 변경여부를 지정
);

BOOL MessageBeep(
   UINT uType
);
//------------------------------------------------------

procedure TForm1.Button1Click(Sender : TObject);
begin
   SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, PChar(0), 0);
   Label1.Caption := 'SCREEN SAVER ON';
end;

procedure TForm1.Button1Click(Sender : TObject);
begin
   SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, PChar(0), 0);
   Label1.Caption := 'SCREEN SAVER OFF';
end;

 

<마우스버튼 개수 알아내기>

//--------------------------------------------------
int GetSystemMetrics(
   int nIndex;    // 시스템에서 사용하는 정보에대한 변수값
);
//--------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
   ButtonNo : integer;

begin
   ButtonNo := GetSystemMetrics(SM_CMOUSEBUTTONS);
   Label1.Caption := IntToStr(ButtonNo)+'개입니다';
end;

 

<WIN.INI파일에 문자열쓰기>

//----------------------------------------------
BOOL WriteProfileString(
LPCTSTR lpszSection, //Win.ini파일 Section명
LPCTSTR lpszKey, //Section에 출력할 Key명
LPCTSTR lpszString //Key에 할당할 문자열
};

// INI파일의 Section, Key, String의 구성형태
// [Section]
// Key = String;
//-----------------------------------------------

procedure TForm1.Button1Click(Sender : TObject);
begin
   WriteProfileString(Edit1.Text, Edit2.Text, Edit3.Text);
   // Win.ini 파일에 Edit 컴포넌트에 입력된문자열을 출력한다.
end;
 


<WIN.INI파일에서 문자열 읽어오기>

//------------------------------------------------------------
DWORD GetProfileString(
   LPCTSTR lpAppName,        // Win.ini파일 Section명
   LPCTSTR lpKeyName,        // Section에 포함되어 있는 Key명
   LPCTSTR lpDefault,            // 함수에러 발생시 되돌려지는 문자열
   LPCTSTR lpReturnedString, // Key에 할당되어 있는 문자열을 읽어오는 문자열의 버퍼의 포인터
   DWORD nSize                    // 문자열 버퍼의 크기
);
//-------------------------------------------------------------

procedure TForm1.Button1Click(Sender : TObject);
var
   retstr : string;
begin
   GetProfileString(Edit1.Text, Edit2.Text, Edit3.Text, retstr,sizeof(retstr));
   Label1.Caption := retstr;
end;
 


<특정 INI 파일에 문자열 쓰기>

//-----------------------------------------------------
BOOL WritePrivateProfileString(
LPCTSTR lpszSection,   // INI파일 Section명
LPCTSTR lpszKey,         // Section에 출력할 Key명
LPCTSTR lpszString,      // Key에 할당할 문자열
LPCTSTR lpszFile          // 문자열을 출력할 INI파일명으로 확장자까지 입력해야한다.
);
//-----------------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
begin
   WritePrivateProfileString(Edit1.Text, Edit2.Text, Edit3.Text, Edit4.Text);
   // Edit4에서 지정한 파일에 각 Edit컴포넌트에 입력된 문자열을 출력한다.
   // 출력하고자 하는 파일이 없을 경우 새로 만든다.
end;

 

<특정 INI 파일에서 문자열 읽어오기>

//----------------------------------------------------------
DWORD GetPrivateProfileString(
   LPCTSTR lpAppName,      // 특정 INI파일 Section명
   LPCTSTR lpKeyName,      // Section에 포함되어 있는 Key명
   LPCTSTR lpDefault,          // 함수에러 발생시 되돌려지는 문자열
   LPTSTR lpReturnedString, // Key에 할당되어 있는 문자열을 읽어오는 문자열버퍼의 포인터
   DWORD nSize,                 // 문자열버퍼의 크기
   LPCTSTR lpFileName        // INI파일명으로 확장자까지 입력해야한다.
);
//-----------------------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
var
   retstr : string;
begin
   GetPrivateProfileString(Edit1.Text, Edit2.Text, Edit3.Text, retstr,sizeof(retstr),Edit4.Text);
   // 특정 INI파일의 지정한 Section 및 Key에 할당된 문자열을 읽어온다.
   // GetPrivateProfileString함수에 지정한 Section이나 Key가 없을 경우
   // Default String을 되돌린다.ㅏ
   Label1.Caption := retstr;
end;

 

<현재 실행중인 OS버전 알아내기>

//-------------------------------------------------------
DWORD GetVersion(VOID)

Platform High order bit Low order byte (major version number)
Windows NT zero 3 or 4
Windows 95 1 4
Win32s with Windows 3.1 1 3
//--------------------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
var
   Version : LongInt;
begin
   Version := GetVersion;
   Label1.Caption := 'Windows ' + IntToStr(LoByte(LoWord(Version))) + '.' +
   IntToStr(HiByte(LoWord(Version)));
   Label2.Caption := 'DOS ' + IntToStr(HiByte(HiWord(Version))) + '.' +
   IntToStr(LoByte(HiWord(Version)));
end;

 

<윈도우 배경화면 바꾸기>

//----------------------------------------------------
BOOL SystemParametersInfo(
   UINT uiAction,    // system parameter to query or set
   UINT uiParam,    // depends on action to be taken
   PVOID pvParam, // depends on action to be taken
   UINT fWinIni       // user profile update flag
);
//----------------------------------------------------
procedure ChangeBatang;
var
   Reg : TRegIniFile;
begin
   Reg := TRegIniFile.Create('Control Panel');
   Reg.WriteString('desktop','Wallpaper','c:\babo.bmp');
   // 바탕화면으로 c:\babo.bmp를 사용함.
   Reg.WriteString('desktop','TitleWallpaper','1');
   Reg.Free;

   SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,
      nil, SPIF_SENDWININICHANGE);
end;

 

<CPU종류 알아내기>

//-------------------------------------------------------------------
VOID GetSystemInfo(
   LPSYSTEM_INFO lpSystemInfo // address of system information structure
);

// SYSTEM_INFO 구조체 내용 - 자세한 사항은 도움말 참조
typedef struct _SYSTEM_INFO { // sinf
   union {
      DWORD dwOemId;
      struct {
         WORD wProcessorArchitecture;
         WORD wReserved;
      };
   };
   DWORD dwPageSize;
   LPVOID lpMinimumApplicationAddress;
   LPVOID lpMaximumApplicationAddress;
   DWORD dwActiveProcessorMask;
   DWORD dwNumberOfProcessors;
   DWORD dwProcessorType;
   DWORD dwAllocationGranularity;
   WORD wProcessorLevel;
   WORD wProcessorRevision;

} SYSTEM_INFO;
//--------------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
   Sysinfo : TSysteminfo;
begin
   GetSystemInfo(Sysinfo);
   case Sysinfo.dwProcessorType of
      386 : Label1.Caption := 'Intel 386 ';
      486 : Label1.Caption := 'Intel 486 ';
      586 : Label1.Caption := 'Intel Pentium';
      4000 : Label1.Caption := 'MIPS R4000';
      21046 : Label1.Caption := 'Alpha 21046'
   end;
end;

 

<메모리상태 알아내기>

//------------------------------------------------------------
BOOL GetDiskFreeSpace(
LPCTSTR lpRootPathName, // 디스크 루트 패스
LPDWORD lpSectorsPerCluster, // 클러스터당 섹터수
LPDWORD lpBytesPerSector, // 섹터당 바이트수
LPDWORD lpNumberOfFreeClusters, // 사용하지 않은 클러스터수
LPDWORD lpTotalNumberOfClusters // 총 클러스터수
);
//------------------------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
var
   MemStat : TMemoryStatus;

begin
   MemStat.dwLength := sizeof(TMemoryStatus);
   GlobalMemoryStatus(MemStat);
   with MemStat do
   begin
      Label1.Caption := Format('%d KB',[Trunc(dwTotalPhys/1024)]); //총메모리
      Label2.Caption := Format('%d KB',[Trunc(dwAvailPhys/1024)]); //MemAvailable
      Label3.Caption := Format('%d %%',[trunc(dwAvailPhys/dwTotalPhys*100)]); //사용메모리
      Label4.Caption := Format('%d KB',[Trunc(dwTotalPageFile/1024)]); //SwapFileSetting
      Label5.Caption := Format('%d KB',[Trunc((dwTotalPageFile-dwAvailPageFile)/1024)]);      
      // SwapFileSize
     
      Label6.Caption := Format('%d %%',[100-trunc(dwAvailPageFile/dwTotalPageFile*100)]);      
      // SwapFileUsage
   end;
end;

 

<OEM 코드페이지 알아내기>

//-------------------------------------
UINT GetOEMCP(VOID);
// OEM 코드값 리턴

437 MS-DOS United States
708 Arabic (ASMO 708)
709 Arabic (ASMO 449+, BCON V4)
710 Arabic (Transparent Arabic)
720 Arabic (Transparent ASMO)
737 Greek (formerly 437G)
775 Baltic
850 MS-DOS Multilingual (Latin I)
852 MS-DOS Slavic (LatinII)
855 IBM Cyrillic (primarily Russian)
857 IBM Turkish
860 MS-DOS Portuguese
861 MS-DOS Icelandic
862 Hebrew
863 MS-DOS Canadian-French
864 Arabic
865 MS-DOS Nordic
866 MS-DOS Russian (former USSR)
869 IBM Modern Greek
874 Thai
932 Japan
936 Chinese (PRC, Singapore)
949 Korean
950 Chinese (Taiwan, Hong Kong)
1361 Korean (Johab)
//------------------------------------------
procedure TForm1.Button1Click(Sender : TObject);
var
   ret : integer;
begin
   ret := GetOEMCP;
   case ret of
      437 : Label1.Caption := 'MS_DOS United States(CP 437)';
      // 리턴값은 아래 설명 참조
      // .....
      default : Label1.Caption := 'Etc';
   end;
end;

 

<토글키 상태 알아내기>

//-----------------------------
SHORT GetKeyState(
   int nVirtKey // 가상키 코드
);

// 키값
VK_CAPITAL Caps Lock키
VK_NUMLOCK Num Lock키
VK_SCROLL Scroll Lock키
//------------------------------
procedure TForm1.Button1Click(Sender : TObjcet);
begin
   if GetKeyState(VK_INSERT) = 1 then
      Label1.Caption := 'ON'
   else
      Label1.Caption := 'OFF';
      // Insert 키가 눌려졌으면 1, 아니면 0을 리턴
      // 다른 토글키도 마찬가지
end;

 

<윈도우즈 가동시간 알아내기>

procedure TForm1.Button1Click(Sender : TObject);
var
   hh, mm, ss : integer;
   ret : LongInt;
   buff : string;
begin
   ret := GetTickCount/1000;
   hh := ret/3600;   // 시간계산

   ret := ret -(3600*hh);
   mm := ret/60 //분 계산

   ret := ret - (60*mm);
   ss := ret; //초 계산

   strcpy(buff,IntToStr(hh)+'시간 '+IntToStr(mm)+'분 '+IntToStr(ss'+초');
   Label1.Caption := buff;
end;

 

<날짜정보 리셋하기>

//-----------------------------------------------------------------
BOOL SetSystemTime(

   CONST SYSTEMTIME *lpSystemTime     // address of system time to set
);

// SYSTEMTIME 구조체
typedef struct _SYSTEMTIME {     // st
   WORD wYear;
   WORD wMonth;
   WORD wDayOfWeek;
   WORD wDay;
   WORD wHour;
   WORD wMinute;
   WORD wSecond;
   WORD wMilliseconds;
} SYSTEMTIME;
//------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
   s_time : TSystemTime;
begin
   s_time.wYear := StrToInt(Edit1.Text);
   s_time.wMonth := StrToInt(Edit2.Text);
   s_time.wDay := StrToInt(Edit3.Text);
   SetSystemTime(s_time);

   Label1.Caption := DateToStr(Now);
end;

 

<윈도우즈 종료시키기>

//----------------------------------------------
BOOL ExitWindowsEx(
   UINT uFlags,                  // shutdown operation
   DWORD dwReserved       // reserved
);
//----------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
   case RadioGroup1.ItemIndex of
      0 : ExitWindowsEx(EWX_FORCE, 0);           // 강제종료
      1 : ExitWindowsEx(EWX_LOGOFF, 0);         // LOG OFF
      2 : ExitWindowsEx(EWX_POWEROFF,0);     // Shut Down & Turn Off
      3 : ExitWindowsEx(EWX_REBOOT, 0);         // Shut Down & Reboot
      4 : ExitWindowsEx(EWX_SHUTDOWN, 0);    // ShutsDown
   end;
end;

 

<환경변수 알아내기>

//---------------------------------------
LPVOID GetEnvironmentStrings(VOID)
//환경변수에 대한 문자포인터를 리턴
//---------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
   Dosenv : Pchar;
   len, i : Integer;
begin
   Dosenv := GetEnvironmentStrings;

   while Dosenv <> '\0' do
   begin
      len := StrLen(Dosenv);
      if (len = 0) then break
      else begin
         Memo1.Lines.Add(Dosenv);
         for i := 0 to len do
         Inc(Dosenv);
      end;
   end;
end;

 

<디스크 볼륨정보 알아내기>

//------------------------------------------------------------------------
BOOL GetVolumeInformation(
   LPCTSTR lpRootPathName,                      // 디스크 루트 패스
   LPTSTR lpVolumeNameBuffer,                  // 볼륨이름에 대한 버퍼 포인터
   DWORD nVolumeNameSize,                     // 볼륨이름 버퍼 크기
   LPDWORD lpVolumeSerialNumber,            // 시리얼 넘버
   LPDWORD lpMaximumComponentLength, // 지정 가능한 파일이름의 최대길이
   LPDWORD lpFileSystemFlags,                  // 파일시스템 플래그
   LPTSTR lpFileSystemNameBuffer,            // 파일시스템 네임버퍼 포인터
   DWORD nFileSystemNameSize                // 파일시스템 네임버퍼 크기
);
//------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
   RPName : Pchar;
   VolBuf : Pchar;
   VolSNum : Longint;
   MaxLen : Longint;
   FileFlags : Longint;
   FileNameBuf : Pchar;
begin
   GetVolumeInformation(RPName, VolBuf, sizeof(VolBuf), VolSNum, MaxLen,
      FileFlags, FileNameBuf, sizeof(FileNameBuf));

   Label1.Caption := RPName;
   Label2.Caption := VolBuf;
   Label3.Caption := IntToStr(VolSNum);
   Label4.Caption := IntToStr(MaxLen);

end;

 

<현재 작업디렉토리 알아내기/지정하기>

//------------------------------------------------
DWORD GetCurrentDirectory(
   DWORD nBufferLength,  // 디렉토리 버퍼의 크기
   LPTSTR lpBuffer            // 디렉토리 버퍼에 대한 포인터
);
//-----------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
   CurrDir : array[0..200] of char;
begin
   GetCurrentDirectory(sizeof(CurrDir), CurrDir);
   // 현재 지정된 디렉토리를 알아낸다.
   Label1.Caption := CurrDir;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   SetCurrentDirectory(Pchar(Edit1.Text));
   // 새로운 디렉토리를 지정한다.
end;

 

<해상도 알아내기>

procedure TForm1.Button1Click(Sender: TObject);
begin
   Label1.Caption := IntToStr(GetSystemMetrics(SM_CXSCREEN)) +
      '*' + IntToStr(GetSystemMetrics(SM_CYSCREEN));
end;

 

<Image의 회전>

 "Here's code to rotate a bitmap 90
 degrees"
 
 From: Dave Shapiro
 
 Counterclockwise, that is. This rotates a 640x480 24-bit bitmap 90 degrees in
 about 2/10 of sec on my P133 (4MB video card, 128MB RAM). It works for
 Delphi 2, and should work for 1 and 3, too.
 
 One thing: This does not work for bitmaps that aren't an integral number of colors
 per pixel. If that's the case, you'll have to do some bit twiddling. I'm working on that
 part right now (I need it too), but it'll be a few days. Anyways, suggestions,
 comments, etc., always welcome.
 
 Special thanks to David Ullrich (ooh, I hope I spelled that correctly) for pointing out
 the non-published-but-public-anyway SaveToStream method for the TBitmap class.
 
 Advance apologies for any formatting problems. Netscape's editor is so ridiculously
 crippled that I can't accomplish anything (give me rtin and vim any day).
 
 
 
 procedure RotateBitmap90Degrees(ABitmap: TBitmap);
 
 const
   BITMAP_HEADER_SIZE = SizeOf(TBitmapFileHeader) +
 SizeOf(TBitmapInfoHeader);
 
 var
   { Things that end in R are for the rotated image. }
   PbmpInfoR: PBitmapInfoHeader;
   bmpBuffer, bmpBufferR: PByte;
   MemoryStream, MemoryStreamR: TMemoryStream;
   PbmpBuffer, PbmpBufferR: PByte;
   PbmpBufferRFirstScanLine, PbmpBufferColumnZero: PByte;
   BytesPerPixel, BytesPerScanLine, BytesPerScanLineR: Integer;
   X, Y, T: Integer;
 
 begin
   {
     Don't *ever* call GetDIBSizes! It screws up your bitmap.
     I'll be posting about that shortly.
   }
 
   MemoryStream := TMemoryStream.Create;
 
   {
    To do: Put in a SetSize, which will eliminate any reallocation
    overhead.
   }
 
   ABitmap.SaveToStream(MemoryStream);
 
   {
    Don't need you anymore. We'll make a new one when the time comes.
   }
   ABitmap.Free;
 
   bmpBuffer := MemoryStream.Memory;
 
   { Set PbmpInfoR to point to the source bitmap's info header. }
   { Boy, these headers are getting annoying. }
   Inc( bmpBuffer, SizeOf(TBitmapFileHeader) );
   PbmpInfoR := PBitmapInfoHeader(bmpBuffer);
 
   { Set bmpBuffer to point to the original bitmap bits. }
   Inc(bmpBuffer, SizeOf(PbmpInfoR^));
   { Set the ColumnZero pointer to point to, uh, column zero. }
   PbmpBufferColumnZero := bmpBuffer;
 
   with PbmpInfoR^ do
   begin
     BytesPerPixel := biBitCount shr 3;
     { ScanLines are DWORD aligned. }
     BytesPerScanLine := ((((biWidth * biBitCount) + 31) div 32) * SizeOf(DWORD));
     BytesPerScanLineR := ((((biHeight * biBitCount) + 31) div 32) * SizeOf(DWORD));
 
     { The TMemoryStream that will hold the rotated bits. }
     MemoryStreamR := TMemoryStream.Create;
     {
      Set size for rotated bitmap. Might be different from source size
      due to DWORD aligning.
     }
     MemoryStreamR.SetSize(BITMAP_HEADER_SIZE  + BytesPerScanLineR * biWidth);
   end;
 
   { Copy the headers from the source bitmap. }
   MemoryStream.Seek(0, soFromBeginning);
   MemoryStreamR.CopyFrom(MemoryStream, BITMAP_HEADER_SIZE);
 
   { Here's the buffer we're going to rotate. }
   bmpBufferR := MemoryStreamR.Memory;
   { Skip the headers, yadda yadda yadda... }
   Inc(bmpBufferR, BITMAP_HEADER_SIZE);
 
   {
    Set up PbmpBufferRFirstScanLine and advance it to end of the first scan
    line of bmpBufferR.
   }
   PbmpBufferRFirstScanLine := bmpBufferR;
   Inc(PbmpBufferRFirstScanLine, (PbmpInfoR^.biHeight - 1) * BytesPerPixel);
 
   { Here's the meat. Loop through the pixels and rotate appropriately. }
 
   { Remember that DIBs have their origins opposite from DDBs. }
   for Y := 1 to PbmpInfoR^.biHeight do
   begin
     PbmpBuffer := PbmpBufferColumnZero;
     PbmpBufferR := PbmpBufferRFirstScanLine;
 
     for X := 1 to PbmpInfoR^.biWidth do
     begin
       for T := 1 to BytesPerPixel do
       begin
         PbmpBufferR^ := PbmpBuffer^;
         Inc(PbmpBufferR);
         Inc(PbmpBuffer);
  end;
       Dec(PbmpBufferR, BytesPerPixel);
       Inc(PbmpBufferR, BytesPerScanLineR);
     end;
 
     Inc(PbmpBufferColumnZero, BytesPerScanLine);
     Dec(PbmpBufferRFirstScanLine, BytesPerPixel);
   end;
 
   { Done with the source bits. }
   MemoryStream.Free;
 
   { Now set PbmpInfoR to point to the rotated bitmap's info header. }
   PbmpBufferR := MemoryStreamR.Memory;
   Inc( PbmpBufferR, SizeOf(TBitmapFileHeader) );
   PbmpInfoR := PBitmapInfoHeader(PbmpBufferR);
 
   { Swap the width and height of the rotated bitmap's info header. }
   with PbmpInfoR^ do
   begin
     T := biHeight;
     biHeight := biWidth;
     biWidth := T;
   end;
 
   ABitmap := TBitmap.Create;
 
   { Spin back to the very beginning. }
   MemoryStreamR.Seek(0, soFromBeginning);
   ABitmap.LoadFromStream(MemoryStreamR);
 
   MemoryStreamR.Free;
 end;
 


<조합형 완성형 체크 프로시져>

Function isKs(buf : PChar) : Integer;
var
 Hangul_Code, ks_count, kssm_count : Integer;
 First,Second : Char;
 ptr,ptr2 : PChar;
begin
 ks_count := 0;
 kssm_count := 0;
 ptr := buf;
 ptr2 := buf;
 while ptr^ <> #0 do
 begin
  first := ptr^;
  INC(ptr,1);
  IF (Ord(first) < $80) then Continue;
  second := ptr^;
  if (ptr - ptr2 > 20480) then break;
  hangul_code := (Ord(First) * 256) + Ord(second);
        //  완성형의 특수문자 코드 검사
  if( ( ((hangul_code > $a1a1) And (hangul_code < $a1ff)) OR
        ((hangul_code > $a2a0) And (hangul_code < $a2e6)) OR
        ((hangul_code > $a3a0) And (hangul_code < $a3ff)) OR
        ((hangul_code > $a4a0) And (hangul_code < $a4ff)) OR
        ((hangul_code > $a5a0) And (hangul_code < $a5f9)) OR
        ((hangul_code > $a6a0) And (hangul_code < $a6e5)) OR
        ((hangul_code > $a7a0) And (hangul_code < $a7f0)) OR
        ((hangul_code > $a8a0) And (hangul_code < $a8ff)) OR
        ((hangul_code > $a9a0) And (hangul_code < $a9ff)) OR
        ((hangul_code > $aaa0) And (hangul_code < $aaf4)) OR
        ((hangul_code > $aba0) And (hangul_code < $abf7)) OR
        ((hangul_code > $aca0) And (hangul_code < $acc2)) OR
        ((hangul_code > $acd0) And (hangul_code < $acf2)) OR
        //  1998.2.21 새로 추가(Cherie)
        (hangul_code = $aec2) OR
        //  완성형 한글코드 검사
        Check_HanRange( hangul_code, $b0a0, $b0ff, 16 ) OR
        Check_HanRange( hangul_code, $c0a0, $c0ff, 9  ) OR
        //  완성형 한자코드 검사
        Check_HanRange( hangul_code, $caa0, $caff, 6  ) OR
        Check_HanRange( hangul_code, $d0a0, $d0ff, 16 ) OR
        Check_HanRange( hangul_code, $e0a0, $e0ff, 16 ) OR
        Check_HanRange( hangul_code, $f0a0, $f0ff, 14 ) ) AND
        //  1998.2.23 새로 추가(Cherie)
        //  조합형 일어의 경우 완성형과 동일한 부분이 있는데,
        //  완성형에서는 거의 사용되지 않는 문자이므로,
        //  아래 코드가 있을경우 무조건 조합형으로 인식
        //  만일 조합형 일어 코드가 아니라면...
      ( NOT (( (hangul_code >= $d000) And (hangul_code <= $d3ff) ) OR
          ( (hangul_code >= $dda1) And (hangul_code <= $de98 )) OR
          ( (hangul_code >= $dba1) And (hangul_code <= $dbc8 )) OR
        //  1998.2.27 새로 추가(Cherie)
        //  조합형 선문자일경우도 무조건 조합형으로 인식
        //  만일 조합형 선문자 코드가 아니라면...
          ( (hangul_code >= $d9b0) And (hangul_code <= $d9cf) ) OR
          ( (hangul_code >= $d4b0) And (hangul_code <= $d4cf) ) ) ) ) then
    begin
      INC(ks_count);
      if ks_count >= KS5061_VERIFY_COUNT then
        break;
    end
    else
    begin
      INC(kssm_count);
      if kssm_count >= KS5061_VERIFY_COUNT then
        break;
    end;
    INC(ptr)
  end;
  //  대부분 조합형보다는 완성형 글이 많으므로 카운트 값이
  //  같을 경우 완성형으로 처리하도록 한다.
  if( ks_count >= kssm_count ) then
    isKS := 0
  else
    isKS := 1;
end;
 


<caption에 여러줄 쓰기>

기존에 caption이 여러줄 올 수가 없었습니다.

다음은 caption에 여러줄을 쓰는 간단한 팁입니다.

 unit Newbtn;

 interface

 uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    stdCtrls;

 type
    TNewButton = class(TButton)

 private
 { Private declarations }
 public
 { Public declarations }
    procedure createParams(var Params: TCreatParams); override
    {생성된 윈도의 형태를 결정하는 메소드를 겹지정합니다.}
 end;

 procedure Register;

 implementation

 {$R *.DFM}

 procedure TNewButton.CreateParams(var Params: TCreatParams);
 begin
    inheritde CreateParams(Params);
    //상위 클래스의 메소드를 먼저 호출한 뒤
    Params.Style := Params.style or BS_TILINE;
    //스타일 형태를 multi-line(다중 라인)으로 설정한다.
 end;

 procedure Register;
 begin
    RegisterComponents('sample',[TNewButton]);
 end;

 end.

 

<파일 다루기>

  파일의 종류를 보면 텍스트 파일과 바이너리 파일이 있다.

 델파이에서는 텍스트 파일은 아주 간단히 액세스가 가능하며, 바이너리 파일도 역시 간단히 액세스를 할 수 있다. 텍스트 파일은 아주 간단하여 초보자도 쉽게 읽고 쓸수 있다는 장점이 있다.

 델파이에서 바이너리 파일은 Typed 파일로 정수나 실수 그리고 레코드 등을 파일로 저장할 수 있도록 한다. 첫 강좌는 파일을 다루는 기본적인 함수와 텍스트 파일을 다루는 방법에 대하여 알아본다.

 1. 파일 변수 선언

 파일 변수란 파일을 제어하기 위한 디스크의 실제적인 파일을 가리키는 변수이며 흔히 파일 핸들이라고 한다. 파일 변수란 복잡한 구성 요소들을 대표하는 변수이며 디스크의 파일과 일단 한 번만 연결해 주면 파일 변수를 통해 간단하게 파일 입출력을 할 수 있다.

 텍스트 파일 타입

 Var
    FH: TextFile;

 FH는 텍스트 파일의 파일 핸들 변수이다.

 

 2. 파일과 핸들 연결

 파일과 핸들을 대응하는 작업은 파일 핸들이 어떤 파일을 가리키는가를 지정해 주는 작업이며 다음의 함수를 사용한다.

 AssignFile(파일핸들, 파일명);

 예: AssignFile(FH, 'C:\autoexec.bat');

 

 3. 파일의 오픈

 파일을 오픈한다는 것은 파일 입출력을 위한 준비 과정이라 하겠다. 파일을 입출력하기 위해서는 파일에서 읽은 내용을 저장할 메모리가 필요하며 또한 파일을 어디쯤 읽고 있는가, 어떤 형태의 파일인가 등의 정보를 기억할 여러가지 내부적인 변수들이 필요하고 에러 처리를 위한 준비가 필요하다. 이런 일체의 작업을 통틀어 파일 오픈이라 한다.

 

 3-1. Rewrite(FileHandle)

 파일로 데이타를 출력하기 위한 파일 오픈 함수이다. 만약 파일이 디스크 상에 없으면 파일을 직접 만들고 파일이 있으면 기존 파일을 삭제한 후 다시 만든다.

 3-2. Reset(FileHandle)

 파일로부터 데이타를 입력하기 위한 파일 오픈 함수이다. 읽기 위해서 오픈한 것이므로 데이터를 출력할 수는 없다. 파일이 디스크상에 존재하지 않으면 에러가 발생한다.

 3-3. Append(FileHandle)

 디스크상의 기존에 있는 파일에 데이터를 추가로 출력하기 위한 파일 오픈 함수이다.

 

 4. 파일 입출력

 파일로부터 데이타를 읽거나 쓸 때 필요한 과정이다.

 ReadLn(FileHandle, Variant);
 WriteLn(FileHandle, Value);

 위의 두 함수가 실제로 텍스트 파일을 읽고 쓰는데 많이 쓰이는 함수이다.

 

 5. 파일 닫기

 입출력을 위하여 파일을 열었으면 원래대로 닫아주어야 한다. 파일을 닫는다는 말은 메모리에서 파일에서 사용된 내용을 제거한다는 것이다.

 CloseFile(FileHandle)

 입출력이 끝난 후에 파일을 닫는 것은 무척 중요한 일이면서도 실수로 빼먹고 안하는 경우가 많은데

 반드시 해 주어야 한다. 그렇지 않으면 말짱하던 파일이 사라진다거나 깨지거나 할 가능성이 있다. 위의 다섯가지 순으로 파일로 작업을 한다.

 

 6. 파일 쓰기

 이제 위의 다섯 가지를 사용하여 파일 쓰기를 하도록 하자.

 Var
    FH: TextFile;

 Begin
    AssignFile(FH, 'C:\DSPF.txt');
    Rewrite(FH);
    WriteLn(FH, '델프동 만세');
    WriteLn(FH, '볼랜드 사용자 그룹 = 델프동');
    CloseFile(FH);
 End;

 FH가 파일 핸들 변수이다 'c:\dspf.txt'파일을 파일 핸들 변수에 할당하고 쓰기 모드로 오픈하였다. WriteLn을 사용하여 파일로 한 라인 출력을 하였다. 마지막으로 파일을 닫는 CloseFile함수가 사용되었다.

 온라인 도움말을 이용하여 WriteLn에 대하여 더 자세히 살펴보기를 바란다.

 

 7. 파일 읽기

 파일로부터 데이터를 읽어 보자. dspf.txt에 저장된 데이터를 읽어 보자.

 Var
    FH: TextFile;
    MyStr: String;

 Begin
    AssignFile(FH, 'c:\dspf.txt');
    Reset(FH);
    While Not Eof(FH) Do Begin
    ReadLn(FH, MyStr);
    ShowMessage(MyStr);
 End;

 CloseFile(FH);

 End;

 파일에서 읽은 데이터를 우리는 스트링 변수에 저장한다. Reset함수는 읽기 모드 오픈이다. Eof(FH)함수는 파일의 끝이다인지를나타낸다. ReadLn을 통하여 MyStr변수에 데이타를 읽어들이고 ShowMessage함수로 화면에 디스플레이하여 주는 것이 파일의 끝일 때까지 반복된다. 마지막에는 CloseFile함수로 파일을 닫는다.

 

 8. 파일 추가

 파일에 데이터를 쓰기에서 발전된 것으로 보면 되겠다... 파일에 데이타가 존재할 때 어떻게 하면 그 파일에 내용을 더할 수 있을까? 그것은 Rewrite대신에 Append함수로 수행할 수 있다.

=======================================================

 델파이는 모든 변수들을 파일로 저장할 수 있도록 하는 기능을 제공하는데 바로 이것이 Typed File이다. 파일로 저장될 때 개별 데이타의 데이터형을 가진다는 것으로 해석하면 될 것이다.

 우선 정수값을 저장하는 파일

 Typed File을 사용하는 방법은 텍스트 파일을 사용하는 방법과 거의 동일하다. 단 타입드 파일 변수를 선언하는 형식적인 차이가 있다.

 선언은

 Var
    TFH: File Of Integer;

 Integer와 같이 어떤 Type이 오는 파일인 Typed File을 선언하는 방법이다.

 

 자 이제 정수형 타입의 파일을 액세스 하자.

 Var
    FH: File Of Integer;
    i : Integer;

 Begin
    AssignFile(FH, 'c:intfile.txt');
    Rewrite(FH);
    For i := 1 To 1000 Do
    Write(FH, i);
    CloseFile(FH);
 End;

 레코드형 Typed File

 위의 예는 단순히 Typed File의 구현은 이렇게 할 수도 있다는 것을 보여주는 예가 되겠다.

 그럼, 레코드를 단위로 파일에 읽고 쓰는 방법에 대하여 알아보자.

 Type
    TMyRec = Record
    Name : String[20];
    Age : Integer;
    Male : Boolean;
 End;

 위의 레코드 선언은 신상의 예가 되는 3개의 필드만을 레코드의 멤버로 선언하였다.

 이런 방법으로 주소록이나 전화번호부, 고객 관리등을 작성한다면 유용하게 쓰일 수 있다.

 아래에서 예를 들어 쉽게 설명하도록 하겠다.

 Var
    MyRec: Array[1..100] Of TMyRec;
    FH: File Of TMyRec;
    i: Integer;

 Begin
    AssignFile(FH, 'c:\recfile.txt');
    Rewrite(FH);
    For i := 1 To 100 Do
       Write(Fh, MyRec[i]);
    CloseFile(FH);
 End;

 TMyRec형의 배열 MyRec을 크기 100으로 선언하고 MyRec 전체를 c:\recfile.txt로 출력한다.

 물론 위의 코드는 출력 예만 보이기 위하여 만든 것이기에 MyRec에는 전혀 쓸모없는 값이 들어 있을 것이다.

 MyRec에 값을 대입해 준 후 파일로 출력하면 레코드 전체가 파일로 저장되며 이 정보는 Read함수를 사용하여 읽어 들일 수 있다.

 

 Random Access

 Typed File에서는 Random Access가 가능하다. 이는 순차 접근(Sequential Access)의 반대의 개념으로 파일에 있는 데이터 중 특정 위치의 데이터를 언제든지 읽을 수 있다.

 파일 입출력은 항상 현재의 위치를 기준으로 수행되며 레코드 하나를 읽으면 현재 위치가 레코드의 길이만큼 증가하여 다음 레코드를 읽을준비를 한다. 현재 위치를 변경하려면 Seek함수를 사용하며 인수로 파일 핸들과 몇번째 레코드를 읽을 것인지 알려주면 된다.

 10번째 레코드를 읽고자 할 때 다음과 같다.

 Seek(FH, 10);
 Read(FH, MyRec[10]);

 파일의 현재 위치를 구하려면 FilePos(FH)함수를 사용하여 파일의 총크기를 구하려면 FileSize(FH)함수를 사용하면 된다.

 

<한, 영 전환하기>

 // 'uses' Clause 에 'Imm' 을 추가함.
 unit Unit1;

 interface

 uses
    Windows,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Imm, StdCtrls;

 type
    TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Label1: TLabel;

 procedure Button1Click(Sender: TObject);
 procedure FormCreate(Sender: TObject);

 private
 { Private declarations }

 public
 { Public declarations }

 procedure ConvK_Emode;
 function GetK_Mode: Boolean;

 end;

 var
    Form1: TForm1;

 implementation

 {$R *.DFM}

 var
    K_Emode : HIMC;
    procedure TForm1.ConvK_Emode;     {한/영 모드 전환 }

begin
    K_Emode := ImmGetContext(handle);

    if GetK_Mode then        {한글모드이면 영문모드로}
       ImmSetConversionStatus(K_Emode, IME_CMODE_ALPHANUMERIC,          IME_CMODE_ALPHANUMERIC)

    else       {영문모드이면 한글모드로}
       ImmSetConversionStatus(K_Emode, IME_CMODE_HANGEUL, IME_CMODE_HANGEUL);

 end;

 function TForm1.GetK_Mode: Boolean;     {한/영 모드 얻기}

var
    Conversion, S: DWORD;

 begin
    K_Emode := ImmGetContext(handle);
    ImmGetConversionStatus(K_Emode, Conversion, S);

    if Conversion = IME_CMODE_HANGEUL then
       GetK_Mode := True
    else
       GetK_Mode := False;

 end;

 procedure TForm1.Button1Click(Sender: TObject);

 begin
    ConvK_Emode;

    if GetK_Mode then Label1.Caption := '한글'
    else Label1.Caption := '영문';
 end;

 procedure TForm1.FormCreate(Sender: TObject);

 begin
    if GetK_Mode then Label1.Caption := '한글'
    else Label1.Caption := '영문';
 end;

 end.

 

<키보드의 임의키 발생>

 아래 예제가 있습니다.

 사용법은 Memo1 에 임의의 문장을 작성한 후 E_VirtualKey 콤포넌트에 문자열" BACK"이라고 입력한 후 SpeedButton1 을 누르시면 한 글자씩 지워집니다.

 다른 키의 조합도 사용해 보세요.

 unit Unit1;

 interface

 uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    Buttons, StdCtrls;

 type
    TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    Memo1: TMemo;
    E_VirtualKey: TEdit;
    procedure SpeedButton1Click(Sender: TObject);
  
 private
 { Private declarations }
 public
 { Public declarations }
 end;

 var
    Form1: TForm1;

 implementation {$R *.DFM}

 procedure SimulateKeystroke(VirtualKey: byte; ScanCode: DWORD);
 begin

    // keybd_event 함수를 사용한 키 조합(down, up) 발생
    keybd_event(VirtualKey,     // 키의 down
       ScanCode,  0,  0);

    keybd_event(VirtualKey,     // 키의 up
       ScanCode, KEYEVENTF_KEYUP, 0);

 end;

 procedure SimulateKeyDown(Key : byte);
 begin
    // keybd_event 함수를 사용한 키 down 발생
    keybd_event(Key, 0, 0, 0);
 end;

 procedure SimulateKeyUp(Key : byte);
 begin
    // keybd_event 함수를 사용한 키 up 발생
    keybd_event(Key, 0, KEYEVENTF_KEYUP, 0);
 end;

 procedure TForm1.SpeedButton1Click(Sender: TObject);
 var
    hs: String;
    w : word;

 begin
    Memo1.SetFocus;
    hs := UpperCase(E_VirtualKey.Text);

    if pos('INS',hs)> 0 then SimulateKeystroke(VK_INSERT, 0) else
    if pos('DEL',hs)> 0 then SimulateKeystroke(VK_DELETE, 0) else
    if pos('RT',hs)> 0 then SimulateKeystroke(VK_RETURN, 0) else
    if pos('TAB',hs)> 0 then SimulateKeystroke(VK_TAB, 0) else
    if pos('ESC',hs)> 0 then SimulateKeystroke(VK_ESCAPE, 0) else
    if pos('BACK',hs)> 0 then SimulateKeystroke(VK_BACK, 0) else
    if pos('UP',hs)> 0 then SimulateKeystroke(VK_UP, 0) else
    if pos('DOWN',hs)> 0 then SimulateKeystroke(VK_DOWN, 0) else
    if pos('LEFT',hs)> 0 then SimulateKeystroke(VK_LEFT, 0) else
    if pos('RIGHT',hs)> 0 then SimulateKeystroke(VK_RIGHT, 0) else
    if pos('PGDN',hs)> 0 then SimulateKeystroke(VK_NEXT, 0) else
    if pos('PGUP',hs)> 0 then SimulateKeystroke(VK_PRIOR, 0) else
    if pos('END',hs)> 0 then SimulateKeystroke(VK_END, 0) else
    if pos('HOME',hs)> 0 then SimulateKeystroke(VK_HOME, 0);
    { ... 이하 가상키의 조합을 발생시킬 수 있습니다}

     // 그리고 위의 SimulateKeyDown, SimulateKeyUp 를 사용하여 Shift, Ctrl, Alt 등은
     // down 상태를 유지하고(SimulateKeyDown), 이를 해제(SimulateKeyUp)할 수 있습니다
     // 또한 일반 문자의 ScanCode는 VkKeyScan() 함수로 알 수 있습니다

 end;

 end.

 

<스크린 해상도 변경>

해상도 변경을 위하여 TDevMode 개체를 사용합니다...

 var
    DevMode : TDevMode;

 를 선언하시고...

 구현부에서는 아래와 같죠...

 With DevMode Do Begin
    dmSize := SizeOf(TDevMode);
    dmPelsWidth := 800;
    dmPelsHeight := 600;
    dmFields := DM_PELSWIDTH Or DM_PELSHEIGHT;
 End;

 스크린 해상도의 변경은 좀 신중을 기해야 겠죠...

 

<DELPHI에서 STRING 가지고 놀기>

String Type 의 변수를 가지고 할 수 있는 일 !

 1. Concat (문자열을 합쳐 준다)

    function Concat(str1, str2: String);string;
       str1 = 첫 번째 문자열
       str2 = 두 번째 문자열

 var
    str : String;

 begin
    str := '멍멍이';
    str := concat(str, '강아지');

 실행 결과 : 멍멍이강아지

 //---------------------
 str := '멍멍이;
 str := str + '강아지';
// -----------------------

 위의 문장과 다를게 없다.

 

 2. Copy (원하는 만큼의 문자열을 RETURN 해 준다)

 function Copy(str: String, Index, Counter: integer);string;
    Index = 시작 위치
    Counter = 시작위치부터의 리턴할 문자열까지의 카운터

 var
    str : String;

 begin
    str := '송아지 망아지';
    str := Copy(str, 1, 6);

 실행 결과 : 송아지

 

 3. Insert (원하는 위치의 문자열을 삽입 시킨다)

 procedure Insert(Source: string; var S: string; Index: Integer);
    Source = 원본 문자열
    S = 삽입시킬 문자열
    index = 삽입시킬 위치

 var
    str: string;

 begin
    str := '강지';
    Insert('아', str, 2);
 end;

 실행 결과 : 강아지

 

 4. Delete (원하는 위치의 문자열을 삭제 한다)

 procedure Delete(var S: string; Index, Count:Integer);
    S = 소스 문자열
    index = 삭제를 시작할 위치
    Count = 시작위치부터의 지울위치까지의 카운터

 var
    s: string;

 begin
    s := '강앙아지';
    Delete(s,3, 2);
 end;

 실행 결과 : 강아지

 

 5. Length (문자열의 길이를 반환 해 준다)

 function Length(S: string): Integer;

    s = 소스 문자열

 var
    s : String
    Len : integer;

 begin
    s := '강아지';
    Len := Length('강아지');

 실행 결과 : 6

 

 6. Pos (찾고자 하는 문자열의 위치를 반환하여 준다)

 Pos(Substr: string; S: string): Integer;
    Substr = 찾고자 하는 문자열
    S = 원본 문자열

 var
    str : String;
    sub : String;
    Position : integer;

 begin
    str := '송아지';
    Position := Pos('아', S);
 end;

 실행 결과 : 3

 

<Tray에 아이콘 넣기>

Win95의 오른쪽 귀퉁이에는 스피커의 볼륨조절과 같은 작은 아이콘들이 있습니다.. 자신의 프로그램을 그곳으로 밀어넣는 방법입니다..

 먼저 트레이에서 발생하는 메세지를 받아야 하므로 메세지를 정해야 합니다. 다음줄을 {$R *.DFM} 아랫줄에 넣어주세요.

 물론 그 한참 위에 넣어도 되지만 다른 유닛에서 쓸게 아니니 아랫쪽에 넣는게 좋죠.

    const MY_SHOWFORM_ID = WM_USER+1;

 이제 넣는 부분입니다. 다음의 코드를 FormCreate에 넣어줍니다.

 

 procedure TfmTrayMain.FormCreate(Sender: TObject);
 var
    iconData : TNotifyIconData;

 begin
    // 폼을 트레이에 넣어준다.
    ShowWindow (Application.Handle, SW_HIDE);
    // 폼이 안 보임
    Application.ShowMainForm:= False;
    with IconData do
    begin
       cbSize := SizeOf ( IconData );
       // 델파이에서는 Wnd로 바뀌었음
       Wnd := Handle;
       uID := 100;
       uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
       uCallbackMessage := WM_USER + 1;
       hIcon := Application.Icon.Handle;
       StrPCopy(szTip, Application.Title);
    end;

    Shell_NotifyIcon( NIM_ADD, @IconData );
 end;

 

 넣기만 하면 안되겠죠.. 마우스로 클릭하면 다시 화면에 표시가 되어야 죽이든지 바꾸든지 할테니까요.. 다음과 같이 다시 살릴 수 있습니다.

 

 // 메세지 프로시져
 procedure TfmTrayMain.WndProc;
 begin
    case Message.Msg of
       MY_SHOWFORM_ID:
    case Message.lParam of
       WM_LBUTTONDBLCLK: Self.Show;
 end;

 end;

 inherited;
 end;

 

 WndProc는 구지 설명할 필요는 없을테구, 모르시는 분을 위해 선언부까지 얹어드립니다.

    procedure WndProc ( var Message : TMessage ); override;

 

<다른 프로그램실행 시킨후 Wait하기>

How do I execute a program and have my code wait until it is finished?

 //-------A: Here is the 16 bit version:

 uses Wintypes,WinProcs,Toolhelp,Classes,Forms;

 Function WinExecAndWait(Path : string; Visibility : word) : word;
 var
    InstanceID : THandle;
    PathLen : integer;

 begin
    { inplace conversion of a String to a PChar }
    PathLen := Length(Path);
    Move(Path[1],Path[0],PathLen);
    Path[PathLen] := #00;
    { Try to run the application }
    InstanceID := WinExec(@Path,Visibility);
    if InstanceID< 32 then    { a value less than 32 indicates an Exec error }
    WinExecAndWait := InstanceID

 else begin
    Repeat
       Application.ProcessMessages;
    until Application.Terminated or (GetModuleUsage(InstanceID) = 0);

    WinExecAndWait := 32;
 end;

 end;


 //--------- Here is the 32 bit version:

 function WinExecAndWait32(FileName:String; Visibility : integer):integer;
 var
    zAppName:array[0..512] of char;
    zCurDir:array[0..255] of char;
    WorkDir:String;
    StartupInfo:TStartupInfo;
    ProcessInfo:TProcessInformation;

 begin
    StrPCopy(zAppName,FileName);
    GetDir(0,WorkDir);
    StrPCopy(zCurDir,WorkDir);
    FillChar(StartupInfo,Sizeof(StartupInfo),#0);
    StartupInfo.cb := Sizeof(StartupInfo);
 
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := Visibility;
    if not CreateProcess(nil,
       zAppName,   { pointer to command line string }
       nil,                { pointer to process security attributes }
       nil,                { pointer to thread security attributes }
       false,            { handle inheritance flag }
       CREATE_NEW_CONSOLE or   { creation flags }
       NORMAL_PRIORITY_CLASS,
       nil,                { pointer to new environment block }
       nil,                { pointer to current directory name }
       StartupInfo,   { pointer to STARTUPINFO }
       ProcessInfo) then Result := -1    { pointer to PROCESS_INF }

    else begin
       WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
       GetExitCodeProcess(ProcessInfo.hProcess,Result);
    end;
 end;

 

<문자열 대.소문자로 바꾸기>

 EDITBOX 같은데서 키보드 입력 제한을 할때 영문(대.소문자)를 가리기 위해 대부분이 keypress 나 keyup 또는 keydown EVENT에서 처리 하는 것으로 알고 있습니다.

  좀 뭐랄까 ??? 약간 무식한 방법이였지요.... 소스코드도 지저분해 지고.......

  EditChange Event에서 다음과 같은 방법을 권합니다.

 

 procedure _MYForm.WoonoEdit1Change(Sender : TObject);
 begin
        WoonoEdit1.CharCase := clLowerCase;
        // 입력 받을때 무조건 영문 소문자로 받는다.
 end;

 

 ecLowerCase : 모든 영문자를 소문자로 받는다.
 ecUpperCase : 모든 영문자를 대문자로 받는다.
 ecNormal       : 모든 영문자를 보통 상태로 유지한다.

 

<파일정보(생성,변경,접근일자,속성,종류...)>

 아래 소스는 파일의 각종 정보를 읽어오는 루틴인데 완전히 모듈화가 된 것은 아니지만, 파일의 생성,변경,접근일자를 읽는 부분이 있어 올립니다  

  function FileSize(hi,lo: integer) :longint; 
  begin
    Result := (hi * MAXDWORD) + lo;
  end;

  // This function retrieves the last time, the given file was written to disk
 function GetLocalTime(a:tfiletime):string;

 var
      mtm:   TSystemTime;
      at:    TFileTime;
      ds,ts: ShortString;

 begin
      filetimetolocalfiletime(a,at);
      filetimetosystemtime(at,mtm);
      SetLength(ds, GetDateFormat(LOCALE_USER_DEFAULT, 0, @mtm, NIL, @ds[1], 255) - 1);
      SetLength(ts, GetTimeFormat(LOCALE_USER_DEFAULT, time_noseconds, @mtm, NIL,
            @ts[1], 255)  - 1);
      Result:=ds+'  '+ts;
 end;

 procedure TFileInfoForm.GetFileInfo(FileName: String);

 var
    SHFinfo: TSHFileInfo;
    FindData: TWin32FindData;    FindHandle :THandle;

 begin
    L_FileName.Caption := ExtractFileName(FileName); // 파일명(Name)
    ShGetFileInfo(PChar(FileName), 0, SHFinfo, SizeOf(SHFinfo), // 파일종류만 알아낸다
                  SHGFI_TYPENAME);
    L_Filetype.Caption := SHFinfo.szTypeName; // 파일종류(Type)
    FindHandle := Windows.FindFirstFile(PChar(FileName), FindData);

    try
      L_Filesize.Caption := FloatToStr(Trunc(FileSize(FindData.nFileSizeHigh,
         FindData.nFileSizeLow) / 1024))+' KB ('+ IntToStr(FileSize(FindData.nFileSizeHigh,
         FindData.nFileSizeLow))+' Bytes)';

      OldAttributes := FileGetAttr(FileName);  // 파일의 속성(attribute)
      CB_ReadOnly.Checked := (OldAttributes and faReadOnly) = faReadOnly;
      CB_Archive.Checked  := (OldAttributes and faArchive) = faArchive;
      CB_System.Checked   := (OldAttributes and faSysFile) = faSysFile;
      CB_Hidden.Checked   := (OldAttributes and faHidden) = faHidden;
       L_Created.Caption    := GetLocalTime(FindData.ftCreationTime);   // 파일생성일(Created)
      L_Modified.Caption   := GetLocalTime(FindData.ftLastWriteTime);  // 파일변경일(Modified)
      L_LastAccess.Caption := GetLocalTime(FindData.ftLastAccessTime);
      // 파일접근일(LastAccess)

    finally
      Windows.FindClose(FindHandle);
    end;
 end;

 

<JPEG 파일 처리>

우선 uses 에 JPEG 를 추가한다.

procedure TForm1.Button1Click(Sender : TObjcect);
var
   TempImg : TImage;
   Jpg : TJPEGImage;
begin
   TempImg:=TImage.Create(Self);
   with TempImg do   begin
      Width:=PaintBox1.Width;
      TempImg.Height:=PaintBox1.Height;
   end;
   Jpg:=TJPEGImage.Create;
   with PaintBox1 do begin
      BitBlt(TempImg.Canvas.Handle,0,0,Width,Height,Canvas.Handle,0,0,SrcCopy);
   end;
   TempImg.Picture.Bitmap.SaveToFile('TempImg.bmp');
   Jpg.Assign(TempImg.Picture.Bitmap);
     //Bitmap File을 Jpeg파일로
   Jpg.SaveToFile('TestImg.jpg');
   TempImg.Free;
   Jpg.Free;
end;

 

다른 방법(함수 이용 - 천리안 류님께서 올린 함수)
* Source

Implementation
uses
   JPeg;
 
procedure LoadJPeg(FileName:String; PicIn:TPicture);
var
   JPegImage : TJPegImage;
begin
   JPegImage:= TJPegImage.Create;
   JPegImage.LoadFromFile(FileName);
   PicIn.Assign(JPegImage);
   JPegImage.Free;
end;
 
procedure TForm1.Button1Click(Sender : TObject);
begin
  if OpenDialog1.Execute then
     LoadJPeg(OpenDialog1.Filename, Image1.Picture);
      //JPEG파일을 로드하여 Image1에 보여줌
end;

 

<Image 컴포넌트 위에 글씨쓰기>

procedure TForm1.Button1Click(Sender: TObject);
var
   OldBkMode : integer;
begin
   Image1.Picture.Bitmap.Canvas.Font.Color := clRed;
   OldBkMode := SetBkMode(Image1.Picture.Bitmap.Canvas.Handle, TRANSPARENT);
   Image1.Picture.Bitmap.Canvas.TextOut(10, 10, 'Hi, I am Park');
   SetBkMode(Image1.Picture.Bitmap.Canvas.Handle, OldBkMode);
end;

 

<파일의 날짜와 시간을 알아내기>

아래 함수를 이용합니다.
function GetFileDate(TheFileName: string): string;
var
   FHandle: integer;
begin
   FHandle := FileOpen(TheFileName, 0);
   try
      Result := DateTimeToStr(FileDateToDateTime(FileGetDate(FHandle)));
   finally
      FileClose(FHandle);
   end;
end;

 

<드라이브에 디스크 존재여부 알아내기>

function DriveReady(Drive : char):Boolean;
var
   OldErrorMode : word;
   OldDir : string;
begin
   OldErrorMode:= SetErrorMode(SEM_NOOPENFILEERRORBOX);
   GetDir(0, OldDir);
   Result:= True;
   try
      ChDir(Drive + ':\');
   except
      Result:= False
   end;
   ChDir(OldDir);
   SetErrorMode(OldErrorMode);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
   if DriveReady('A') then ShowMessage('Drive is Ready')
   else ShowMessage('Drive not Ready');
end;

 

<화면 캡쳐하여 저장하기>

procedure TForm1.Button1Click(Sender: TObject);
var
   DeskTop : TCanvas ;
begin
   DeskTop := TCanvas.Create ;
   try
   with DeskTop do
      Handle := GetWindowDC (GetDesktopWindow) ;
   with PaintBox1.Canvas do
   CopyRect (Rect (0, 0, Width, Height),   DeskTop, Rect (0, 0, Width, Width))
   finally
      DeskTop.Free
   end;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
   MyBmp: TBitmap;
begin
   MyBmp := TBitmap.Create;
   with MyBmp do begin
     Height := PaintBox1.Height;
     Width := PaintBox1.Width;
     Canvas.CopyRect (Rect (0, 0, Width, Height), PaintBox1.Canvas, Rect (0, 0, Width, Height));
     SaveToFile('c:\Grim.bmp');
   end;
      MyBmp.Free;
end;

 

<텍스트 문서 미리보기>

솔직히 미리보기라기 보다는 텍스트 파일의 내용을 Bitmap파일로 변환하여 저장합니다.
procedure TForm1.Button1Click(Sender: TObject);
var
   Bmp : TBitmap;
   Line : string;
   I : integer;
   ch : char;
   F : TextFile;
begin
   I := 0;
   Bmp := TBitmap.Create;
   with Bmp do begin
      Width := ClientRect.Right;
      Height := ClientRect.Bottom;
      AssignFile(F, 'c:\mytext.txt'); {저장하고자 하는 파일명을 삽입}
      Reset(F);
      repeat
        Inc(I);
        Line := '';
        repeat
          Read(F, ch);
          Line := Line+ch;
       until ch= #10;
       Canvas.TextOut(10, I*20, Copy(Line, 1, Length(Line)-2));
      until EOF(F);
   CloseFile(F);
   BitBlt(Canvas.Handle, 0, 0, Width, Height, GetDc(Handle),  ClientRect.Left, ClientRect.Top, SRCCOPY);
   SaveToFile('c:\preview.bmp');
   Free;
   end;
end;

 

<폼의 크기 제한하기>

폼의 크기를 조절할 때 최대, 최소의 크기제한을 두려면
"WM_GETMINMAXINFO"의 메시지 핸들러를 작성해야 한다.
type
   TForm1 = class(TForm)
     procedure FormCreate(Sender: TObjcet);

   private
     MinSize : TPoint;       //최소크기 제한
     MaxSize : TPoint;      //최대크기 제한
     procedure WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo);
     message WM_GETMINMAXINFO;
     //메시지 WM_GETMINMAXINFO에 반응하는 메소드

   public
end;
 
procedure TForm1.WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo);
begin
   if visible then begin
   Msg.MinMaxInfo^.PtMinTrackSize := MinSize;
   Msg.MinMaxInfo^.PtMaxTrackSize := MaxSize;
   end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);  //최대,최소 사이즈 지정
begin
   MaxSize.X := 200;   
   MaxSize.Y := 500;
   MinSize.X := 100;
   MinSize.Y := 200;
end;

 

<마우스 동작범위 제한하기>

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
   R : TRect;
begin
   R := BoundsRect;
   InflateRect(R,-30,-30);
   ClipCursor(@R);
end;
 
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
   ClipCursor(Nil);
end;

 

<스플레시 화면 만들기>

프로그램 시작시 나타나는 로고화면을 제작하는 방법이다. 이는 프로젝트파일(.dpr)를 직접
수정해야만 한다.
Project Option에서 SplashForm을  Available forms로 옮긴다.
program project1;
 
uses
   Forms,
   Unit1 in 'Unit1.pas' {Form1},
   Splash in 'Splash.pas' {SplashForm},
 
{$R *.RES}
begin
  SplashForm := TSplashForm.Create(Application);
  SplashForm.Show;
  SplashForm.Update;
  Application.CreateForm(TForm1, Form1);
  SplashForm.Hide;
  SplashForm.Free;
   Application.Run;
end.

 

<구멍난 폼 만들기>

하나의 폼 위에 다섯개의 판넬을 올려놓고 각각의 속성을  아래의 '표1' 과 같이 설정하고,
폼의 OnResize이벤트 헨들러를 생성 해 아래의 코드를 입력하자.
 
procedure TForm1.FormResize(Sender: TObject);
var
   WindowRgn, HoleRgn : HRgn;
begin
   WindowRgn := 0;
   GetWindowRgn(Handle, WindowRgn);
   DeleteObject(WindowRgn);
   WindowRgn := CreateRectRgn(0,0,Width, Height);
   HoleRgn := CreateRectRgn(Panel3.Width + 6, Panel1.Height + 25,
                   Width - (Panel4.Width + 6), Height - (Panel2.Height + 6));
   CombineRgn(WindowRgn, WindowRgn, HoleRgn, RGN_DIFF);
   SetWindowRgn(Handle, WindowRgn, TRUE);
   DeleteObject(HoleRgn);
end;
 
표1
---------------------------------
Panel1
---------------------------------
Align alTop
BevelOuter bvNone
Caption
Height 17
---------------------------------
Panel2
---------------------------------
Align alBottom
BevelOuter bvNone
Caption
Height 17
---------------------------------
Panel3
---------------------------------
Align alRight
BevelOuter bvNone
Caption
Width 17
---------------------------------
Panel4
---------------------------------
Align alRight
BevelOuter bvNone
Caption
Width 17
---------------------------------
Panel5
---------------------------------
Align alClient
BevelOuter bvLowered
Caption
---------------------------------

 

<원형 폼 만들기>

procedure TForm1.FormCreate(Sender : TObjcet);
var
   MyForm : HRGN;
begin
   MyForm := CreateEllipticRgn(0, 0, Width, Height);  //타원의 폼 설정
   SetWindowRgn(Handle, MyForm, TRUE);
end;
procedure TForm1.FormDestory(Sender : TObject);
begin
   DeleteObject(MyForm);
end;

 

<다각형의 폼 만들기>

다각형의 폼도 마찬가지로 CreatepolygonRgn함수를 사용해 만들 수 있다.
아래와 같이 하면 역삼각형의 폼이 만들어진다.
procedure TForm1.FormCreate(Sender : TObject);
var
   MyForm : HRGN;
   Pixel : array[0..2] of TPoint;
begin
   Pixel[0] := Point(0, 0);        //폼의 좌표를 설정
   Pixel[1] := Point(Width, 0);
   Pixel[2] := Point(Width div 2, Height);
   MyForm := CreatePolygonRgn(Pixel, 3, ALTERNATE);
   SetWindowRgn(Handle, MyForm, TRUE);
end;

 

<힌트의 속성바꾸기>

델파이에서는 힌트속성을 쉽게 구현할 수 있는 반면 힌트의 속성을 바꿀 수 있는 프로퍼티가 없습니다.
아래의 방법을 통해 속성을 바꿔보세요.
....
type
  TUserHint = class(THintWindow)
  constructor Create(AOwner: TComponent); override;
end;                                         //interface부에 삽입
...
constructor TUserHint.Create;
begin
   inherited Create(AOwner);
   Canvas.Font.Name := '궁서체';    // 원하는 폰트의 이름 지정
   Canvas.Font.Size := 10;              // 원하는 폰트의 사이즈 지정   
   Canvas.Brush.Color := clYellow;  // 원하는 바탕색 지정
end;                                             // implementation부에 삽입
 
procedure TForm1.FormCreate(Sender: TObjcet);
var
   OldHint : Boolean;
begin
   OldHint := Application.ShowHint;
   Application.ShowHint := False;
   HintWindowClass := TUserHint;
   Application.ShowHint := OldHint;
end;
end.

 

<상태바에 힌트보이기>

public
{ Public declarations }
   procedure ShowHint(Sender : TObject);  //힌트를 보이기위한 프로시저
end;
 
procedure TForm1.ShowHint(Sender : TObject);
begin
    StatusBar1.Panels[0].Text := Application.Hint;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
    Application.HintPause := 100;  //힌트가 나타나는 속도조절
    Application.OnHint := ShowHint;
end;
또한 힌트와 상태바에 동시에 힌트를 나타내고자 하는 경우에는 Hint속성을 '|'문자를 끊어서
동시에 지정할 수 있다. ("풍선도움말|OnHint이벤트에서 사용할 힌트")

 

<Drive Type을 알아내자>

임의의 드라이브 타입을 알려면, 윈도우 API 함수 중 GetDriveType이라는 함수를 사용하면 된다.

 

procedure TForm1.Button1Click(Sender: TObject);

var
   Drive: Char;
   DriveLetter: String[4];

begin
   for Drive := 'A' to 'Z' do
   begin
      DriveLetter := Drive + ':\';
      //  Syntax
      //  GetDriveType(
      //  lpRootPathName: PChar   {a pointer to the root path string}
      //  ): UINT;                 {returns a value based on the drive type}

      case GetDriveType(PChar(Drive + ':\')) of
         Drive_UnKnown : ListBox1.Items.Add( DriveLetter + ': 알 수 없는 드라이브');
         Drive_Removable: ListBox1.Items.Add( DriveLetter + ' : 플로피 드라이브');
         Drive_Fixed:      ListBox1.Items.Add( DriveLetter + ' : 하드 드라이브');
         Drive_Remote:    ListBox1.Items.Add( DriveLetter + ' : 네트워크 드라이브');
         Drive_Cdrom:     ListBox1.Items.Add( DriveLetter + ' : CD-Rom 드라이브');
         Drive_RamDisk:   ListBox1.Items.Add( DriveLetter + ' : RamDisk 드라이브');
      end;
   end;
end;


[TMemo Component] 현재 라인번호 알아내기

메모에서 현재 Caret이 위치하고 있는 줄이 몇 번째 줄인지를 리턴한다.

Label1.Caption := IntToStr(GetCurrLine(Memo1));

function GetCurrLine(Memo : TMemo) : integer;
begin
      Result := Memo.Perform(EM_LINEFROMCHAR, Memo.SelStart, 0);
end;

 

[TMemo Component] 현재 컬럼번호 알아내기

메모에서 현재 Caret이 위치하고 있는 줄에서 몇 번째 컬럼인지를 리턴한다.

Label1.Caption := IntToStr(GetCurrCul(Memo1));

function GetCurrCul(Memo : TMemo)) : integer;
begin
     Result := Memo.SelStart - Memo.Perform(EM_LINEINDEX, GetCurrLine(Memo), 0);
end;

 

[TMemo Component] Caret를 원하는 라인으로 이동하기

Caret을 원하는 위치로 이동시키는데 이때 넘겨주는 값이 라인의 한계를 벗어나면 그 안 범위로 위치시킨다.

만약 라인의 맨끝으로 이동시키고 싶다면 아주 큰값을 주면된다.

SetCurrLine(Memo1. 10);

procedure SetCurrLine(Memo : TMemo; Value : integer);
begin
   if Value < 0 then Value := 0;
   if Value > Memo.Lines.Count then Value := Memo.Lines.Count;
   Memo.SelLength := 0;
   Memo.SelStart := Memo.Perform(EM_LINEINDEX, Value, 0);
end;

[TMemo Component] Caret을 원하는 컬럼으로 이동하기

SetCurrCul(Memo1. 10);

procedure SetCurrCul(Memo : TMemo; Value : integer);
var
   CurrLine : integer;
begin
   CurrLine := GetCurrLine(Memo);
   if Value < 0 then Value := 0;
   if (Value > Length(Memo.Lines[CurrLine])) then
      Value := Length(Memo.Lines[CurrLine]);
   Memo.SelLength := 0;
   Memo.SelStart := Memo.Perform(EM_LINEINDEX, CurrLine, 0) + Value;
end;

 

[TMemo Component] Text가 쓰여지는 영역 알아내기

현재 Text가 쓰여지는 영역을 TRect형으로 리턴한다.

즉 글자의 높이가 10이고 메모의 높이가 25라면 2라인만이 그려지게 된다.

따라서 글자가 그려지는 정확한 영역을 알아내기 위해서는 아래 함수를 사용한다.

Rect := GetTextRect(Memo1);

function GetTextRect(Memo : TMemo) : TRect;
var
   lParam : TRect;
begin
   Memo.Perform(EM_GETRECT, 0, Integer(@lParam));
   Result := lParam;
end;

 

[TMemo Component] 메모에서 현재 보이는 라인수 알아내기

Label1.Caption := IntToStr(GetVisibleLine(Memo1));

function GetVisibleLine(Memo : TMemo) : integer;
var
   Metric : TTextMetric;
   DC : hDC;
begin
   DC := GetWindowDC(Memo.Handle);
   GetTextMetrics(DC, Metric);
   Result := (GetTextRect(Memo).Bottom div Metric.tmHeight);
end;

 

[TMemo Component] 원하는 라인만큼 스크롤하기

현재상태에서 원하는 x, y만큼 스크롤한다.

DoScroll(Memo1, 10, 10);

procedure DoScroll(Memo : TMemo; x : integer; y : integer);
begin
   Memo.Perform(EM_LINESCROLL, x, y);
end;

 

[TRichEdit Component] 블록설정부분 폰트 변경하기

리치에디트컴포넌트는 메모컴포넌트와는 달리 설정부분만 폰트를 변경한다던가, 정렬상태를 바꾸는게 가능하다.

procedure TForm1.FontBtnClick(Sender : TObject);

begin
   if RichEdit1.SelLength > 0 then
   begin
      FontDialog1.Font.Assign(RichEdit1.DefAttributes);
     if FontDialog1.Execute then
         RichEdit1.SelAttributes.Assign(FontDialog1.Font);
   end

   else
     ShowMessage('No Text Selected');
end;

  

[TRichEdit Component] 블록설정부분 속성 변경하기

아래의 소스는 굵게(Bold) 속성을 지정한다.

이탤릭(fsItalic), 밑줄(fsUnderLine) 등의 속성도 마찬가지로 바꿀 수 있다.

procedure TForm1.BoldBtn(Sender : TObject);
begin
   if BoldBtn.Down then
      RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style + [fsBold]
   else
      RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style - [fsBold];
end;

 

[TRichEdit Component] 블록설정부분 복사, 삭제, 잘라우기, 붙이기 설정방법

interface부의 uses절에 Clipbrd를 추가한다.

procedure TForm1.CopyBtnClick(Sender : TObject);
begin
   RichEdit1.CopyToClipboard;  {복사}
   RichEdit1.CutToClipboard;   {잘라두기}
   RichEdit1.ClearSelection;  {지우기 - 클립보드에 저장되지 않는다}
   if Clipboard.HasFormat(CF_TEXT) then begin
      PasteBtn.Enabled := True;   {복사가 되었으면붙이기 버튼을 활성화}
   end;
end;

procedure TForm1.PasteBtnClick(Sender : TObject);
begin
   RichEdit1.PasteFromClipboard;
end;

 

[TRichEdit Component] Insert 키 상태 알아내기

이 소스는 RichEdit 컴포넌트에서만 사용할 수 있다.(메모컴포넌트는 삽입, 수정의 개념이 없음)

procedure TForm1.RichEdit1Key(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  ret : integer;
begin
   ret := GetKeyState(45);
   if ret=1 then
      Label1.Caption := 'Overwrite'
   else
      Label1.Caption := 'Insert';
end;

 

[Find Dialog Component] 리치에디트에서 문자열찾기

먼저 폼에 Memo, FindDialog컴포넌트를 배치합니다. 델파이 도움말에서 참조했습니다.

procedure TForm1.FindBtnClick(Sender : TObject);
begin
   FindDialog1.Execute;
   { or ReplaceDialog1.Execute;}
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
   SelPos: Integer;
begin
   with TFindDialog(Sender) do
   begin
      { Perform a global case-sensitive search for FindText in Memo1 }
      SelPos := Pos(FindText, Memo1.Lines.Text);
      if SelPos > 0 then 
      begin
         Memo1.SelStart := SelPos - 1;
         Memo1.SelLength := Length(FindText);
       end
     
      else MessageDlg(Concat('Could not find "', FindText, '" in Memo1.'),
          mtError,[mbOk], 0);
   end;
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);
var
   SelPos: Integer;
begin
   with TReplaceDialog(Sender) do
   begin
     { Perform a global case-sensitive search for FindText in Memo1 }
     SelPos := Pos(FindText, Memo1.Lines.Text);
     if SelPos > 0 then
     begin
        Memo1.SelStart := SelPos - 1;
        Memo1.SelLength := Length(FindText);
        { Replace selected text with ReplaceText }
        Memo1.SelText := ReplaceText;
      end
   
     else MessageDlg(Concat('Could not find "', FindText, '" in Memo1.'),
          mtError,[mbOk], 0);

   end;
end;

 

<System Modal 폼을 만들려면>

Windows API 함수인 SetSysModalWindow를 사용하면 가능합니다.

다음은 System Modal 창을 보여주는 간단한 예제입니다.

procedure TMainForm1.Create(Application) do
begin
   SetSysModalWindow(Handle);
end;

 

<.RES 화일에서 비트맵을 불러오려면>

다음과 같이 선언합니다.

implementation
{$R C:\Delphi\MyDir\MyRes.Res} <- .RES 화일이 있는 경로명과 파일명

위와 같이 선언한 후에 사용시에는 다음과 같이 Windows API함수를 이용합니다.

Image1.Picture.Bitmap.Handle := LoadBitmap(HInstance, 'BITMAP1');

 

<Win95 와 W3.X 를 구별하는 법>

Windows API 함수인 GetVersion 을 쓰시면 가능합니다.

다음은 버튼을 누르면 윈도우의 버전을 보여줍니다.

procedure TForm1.Button1Click(Sender: TObject);
Var
   x :longint;
   y,z :integer;
begin
   x := GetVersion;
   y := integer(x and $ff);
   z := integer((x shr 8) and $ff);
   Edit1.Text := IntToStr(y);
   Edit2.Text := IntToStr(z);
end;

 

<마우스 커서를 보이지 않게 하려면>

Window API함수인 ShowCursor 에서 값을 False로 줍니다.

 

<정의된 message handler에 다른 작업을 추가하려면>

예를 들어 CM_DIALOGKEY message가 발생되었을 때 원하는 작업을 추가하려고한다면 public section에 다음과 같이 선언합니다.

Procedure CMDialogKey(var Message: TCMDialogKey);message CM_DIALOGKEY;

procedure이름을 message 이름에서 _(밑줄) 표시를 뺍니다. procedure의 정의는 다음과 같습니다.

Procedure TForm1.CMDialogKey(var Message: TCMDialogKey);
begin
   if CharCode = VK_TAB then begin
      {Process the Alt+Tab key here}
      result := 1;
      exit;
   end;
   inherited;
end;

result를 1로 setting하면 더 이상 실행시키지 않고 중단시키겠다는 뜻이고, inherited문은 parent handler로 제어를 보냄을 의미합니다. 모든 작업을 일일이 처리하고자 하지 않으면 inherited문을 사용하십시오.

 

<Run-Time시에 DLL을 Load하고 Free 시키는 방법>

Windows API 함수인 LoadLibrary를 쓰면 Load가 가능합니다. 또한 FreeLibrary를 쓰면 메모리에서 제거할 수 있습니다.

 

<비정상적으로 종료된 DLL 프로그램을 강제적으로 unload 하는 방법>

Windows API 함수인 GetModuleHandle은 DLL의 handle을 돌려주므로ModuleHandle이 0을 리턴할 때 까지 freelibrary를 call한다. 만약에 DLL이 다른 DLL을 Load 했다면 child DLL을 먼저 free시킨다.

 

<DLL의 data segment를 fixed에서 movable로 바꾸는 방법>

DLL 외부에서 GlobalPageUnlock(DSEG)를 부르면 됩니다. 이 함수는DLL 소스에서 Pointer등을 이용하지 않는다면 정상적으로 실행될 것입니다.

 

<최소화되어 있는 Icon을 안보이게 하는 방법>

SetWindowPos나 MoveWindow를 이용하여 좌표값을 음수로 주면 됩니다.

 

<외부의 Exe 화일 호출하는 방법>

Windows API 함수인 WinExec 를 사용하면 됩니다. 다음은 간단한 예제 코드입니다.

WinExec('프로그램명', SW_SHOW);

 

<Title Bar가 없는 Form을 움직이게 하려면>

폼위에서 마우스 커서가 움직이면, 윈도우는 폼에 WM_NCHitTest 메시지를보냅니다. 이 때 폼은 마우스가 폼의 어느 위치에 있는지를 메시지로 주게 됩니다. 마우스의 버튼을 누르는 것과 같은 event가 발생하면 윈도우는 이 정보를 써서 특정행동을 수행하게 되는 것입니다.

다음은 WM_NCHitTest 메시지가 특정한 값을 주는 예제 코드입니다.

procedure TNoCapForm.WMNCHitTest(var Msg: TMessage);
begin
   if GetAsyncKeyState(VK_LBUTTON) < 0 then
      Msg.Result := HTCAPTION
   else
      Msg.Result := HTCLIENT;
end;

 

<Resource를 동적으로 load/free 하는 방법>

Windows가 제공하는 LoadResource(), FreeResource() API 함수를사용합니다.

 

<System 또는 User resource, memory 상태를 구하는 방법>

Windows API를 이용하면 됩니다. GetFreeSystemResource 함수를 참고하시면 됩니다.

다음은 버튼을 누르면 시스템 자원을 보여주는 간단한 코드입니다.

procedure TForm1.Button1Click(Sender: TObject);
begin
   Label1.Caption := IntToStr(GetFreeSystemResources(GFSR_SYSTEMRESOURCES));
   Label2.Caption := IntToStr(GetFreeSystemResources(GFSR_USERRESOURCES));
   Label3.Caption := Formatfloat('#,##0', (GetFreeSpace(0) div 1000));
end;

 

<Visual Basic의 DoEvent와 같은 기능을 사용하려면>

다음과 같이 함수를 만드실 수 있습니다.

function DoEvents: Boolean;
var msg: TMsg;

begin
   while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
   begin
      if msg.message = WM_QUIT then
      begin
         PostQuitMessage(msg.wParam);
         DoEvents := true;
         exit;
      end
     
      else
      begin
         TranslateMessage(msg);
         DispatchMessage(msg);
      end;
   end;
   DoEvents := false;
end;

 

<프로그램의 실행이 끝나기를 기다리는 법>

WinExec 함수는 핸들을 돌려주므로, 이것을 이용합니다.

procedure SomeProc;
var
   ProgramHandle : THandle;
begin
   ProgramHandle := WinExec('C:\Program.exe', SW_SHOWNORMAL);

   {프로그램이 종료될 때까지 반복}
   while GetModuleusage(ProgramHandle) <> 0 do application.processmessages;
end;

 

<프로그램 실행중에 잠시 멈추고 다른 프로세스를 실행시키려면>

다음과 같은 코드를 작성하실 수 있습니다.

procedure TForm1.Delay(msecs:integer);
var
   FirstTickCount:longint;
begin
   FirstTickCount:=GetTickCount;

   repeat
   {실행을 잠시 중지하고 다른 프로세스를 실행합니다.}
      Application.ProcessMessages;
      until ((GetTickCount-FirstTickCount) >= Longint(msecs));
end;

참고로 Application.ProcessMessage 는 메시지 큐에 쌓여있는 메시지중 하나를처리하고 메시지가 큐에 없으면 false를 리턴합 니다.

 

<control의 handle이나 ID를 얻는 방법>

control object의 pointer를 알고 있다면 PointerToMyControl^.HWindow가 바로 window handle입니다.

만약, control의 handle을 알고 있다면 GetDlgCtrlID() API 함수는 ID를 돌려줍니다.

ControlID := GetDlgCtrlID(ControlHandle);

만약 contorl의 pointer를 모르고 ID만 알고 있다면, GetDlgItem() API 함수는handle을 돌려줍니다.

ControlHandle := GetDlgItem(DialogHandle, ControlID);

 

<프로그램이 실행된 디렉토리를 알 수 있는 방법>

다음의 함수는 Application이라는 개체의 ExeName 속성으로부터 디렉토리 경로를 추출해 냅니다.

function GetExePath : String;
var
   LastBackSlashPos, Index : Integer;
begin
   Result := Application.ExeName;
   for Index := 1 to length(Result) do
   if Result[Index] = '\' then LastBackSlashPos := Index;

   {'\' 기호가 붙지 않도록 하려면 LastBackSlashPos 에서 1을 빼야합니다. }
   Result[0] := chr(LastBackSlashPos - 1);
end;

 

<Directory를 만드는 방법>

MKDIR procedure를 이용하면 됩니다.

MkDir('C:\Delphi\MyDir');

 

<MediaPlayer를 이용하지 않고 sound를 발생할 수 있는 방법>

mmSystem에 있는 SndPlaySound Function을 이용하면 됩니다.

SndPlaySound('C:\Windows\Ding.WAV', snd_Async);

 

<Windows의 Message를 처리하는 방법>

다음 Windows 메시지를 처리하는 procedure를 참고하십시오.

procedure YieldToOthers ;
var MSG : TMSG ;
begin
   while PeekMessage(MSG, 0,0,0,PM_REMOVE) do begin
      if Msg.Message = WM_QUIT then exit ;
      TranslateMessage(Msg) ;
      DispatchMessage(Msg) ;
   end ;
end ;

 

<Windows의 Main Message Procedure를 만드는 방법>

다음 예제 procedure를 참고하십시오.

procedure TForm1.ClientWndProc(VAR Message: TMessage);
begin
   with Message do
   case Msg of
      WM_MOUSEMOVE : Memo1.Lines.Add('Mouse Move') ;
      WM_LBUTTONDOWN : Memo1.Lines.Add('LeftButton Down') ;
   else
      Result := CallWindowProc(FPrevClientProc, Handle, Msg, wParam, lParam);
   end;
end;

 

<다른 Application의 메뉴 기능을 실행하도록 하려면>

다음 예제 procedure를 참고하십시오.

CurrWnd := GetWindow(application.handle, gw_hwndfirst);
length := GetWindowText(Currwnd, tmpstr, 255);

if length > 0 then
begin
   if (pos('훈민정음', strpas(tmpstr)) > 0) and (strpas(pAttach^.filepath.tmpstr)<> nil) then
      CurrWnd := 0;
end;

tmpname := ExtractFilename(strpas(pAttach^.filepath));

While CurrWnd <> 0 do
begin
   length := GetWindowText(Currwnd, tmpstr, 255);

   if (length > 0) and (pos('훈민정음', strpas(tmpstr) > 0) and (pos(tmpname,StrPas(tmpstr)) > 0) then
   break;

   CurrWnd := GetWindow(CurrWnd, GW_HWNDNEXT);
   Application.ProcessMessages;
end;

Handle := CurrWnd;

if Handle <> 0 then
begin
   SendMessage(Handle, WM_COMMAND, 4005, 0);
   SendMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, 0);
end;

 

<폼이 최소화 되지 못하도록 하려면>

다음과 같이 WM_SYSCOMMAND 메시지를 처리하면 됩니다.

type
   TForm1 = class(TForm)
public :
   procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
end;

procedure TForm1.WMSysCommand(var Msg:TWMSysCommand) ;
begin
   {최소화/최대화 버튼을 누를때 아무 작용을 하지 않게 합니다}
   if (Msg.CmdType = SC_MINIMIZE) or (Msg.CmdType = SC_MAXIMIZE) then
      Msg.CmdType := SC_RESTORE;

   DefaultHandler(Msg);
end;

 

<DPR 화일의 Application.Run이 실행되기 전에 Windows 메시지를 가로채는방법>

다음과 같이 새로운 Windows Message procedure를 정의하고 그것을Main Windows procedure로 설정합니다. 다음 예제 procedure를 참고하십시오.

program Project1;

uses
   Forms, messages, wintypes, winprocs,
   Unit1 in 'UNIT1.PAS';

{$R *.RES}

var
   OldWndProc: TFarProc;

function NewWndProc(hWndAppl: HWnd; Msg, wParam: Word; lParam: Longint):Longint; export;
begin
   result := 0; { Default WndProc return value }

   {message 처리 루틴이 들어갈 곳}

   result := CallWindowProc(OldWndProc, hWndAppl, Msg, wParam, lParam);
end;

begin
   Application.CreateForm(TForm1, Form1);
   OldWndProc := TFarProc(GetWindowLong(Application.Handle, GWL_WNDPROC));
   SetWindowLong(Application.Handle, GWL_WNDPROC, longint(@NewWndProc));
   Application.Run;
end.

 

<Task Handling 방법>

ToolHelp unit에 정의되어 있는 함수들을 이용하면 됩니다. 다음은 TaskFirst, TaskNext 등을 이용한 예제입니다.

function isTaskInstance(HInst : Longint) : Boolean;
var CurrentTask : TTaskEntry;
   Success : boolean;
begin
   Result := false;
   Yield;
   CurrentTask.dwSize := SizeOf(CurrentTask);
   Success := TaskFirst(@CurrentTask);
   while Success do begin
      if CurrentTask.HInst = HInst then begin
         Result := true;
         exit;
      end;
      Success := TaskNext(@CurrentTask);
   end;
end;

 

<MDI 어플리케이션에서 focus를 가지고 있는 form이 어느 것인지 알수 있는 방법>

TForm의 ActiveMDIChild property를 이용합니다.

if Application.MainForm.ActiveMDIChild as TEditForm then
TEditForm(ActiveMDIChild).Save1Click(Sender);

 

<Delphi의 MDI에서 title bar가 없는 child form 을 만드는 방법>

다음과 같이 MDI Parent Form에 코드를 입력하시면 가능합니다.

type
   TForm1 = class(TForm) {TForm1 는 child form의 이름입니다.}
   procedure CreateParams(var Params: TCreateParams);
   override;
end;

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
   inherited CreateParams(Params);
   Params.Style := Params.Style and not WS_OVERLAPPEDWINDOW or WS_BORDER ;
end;

 

<MDI application에서 특정 child를 항상 일정한 크기/위치로 고정하는방법>

Child Form의 onActivate event에서 다음과 같이 크기와 위치를 정해주면됩니다.

procedure TEditForm.FormActivate(Sender: TObject);
begin
   Left := 200;
   Height := 140;
end;

단, 이 이후에 생성하는 child form은 윈도우의 기본 특성에 따라 다른 위치로생성됩니다.

 

<MDI에서 차일드 윈도우의 위치 지정>

사용자가 Run-Time시에 Child Windows를 열면 각각은 이전 윈도우의 약간 우측 아래에 위치하게 됩니다. 이렇게 하고 싶지 않을 경우 어떻게 해야 합니까?


이것은 MDI 윈도우가 어떻게 작업하느냐 입니다. VCL은 이 상황에서윈도우의 기본적인 행동을 무시하진 못합니다.

단, Position Property 에서 poScreenCenter 값을 사용할 수 있습니다. 그러나 이 속성을 선택하면 child form이 항상 Parent Form의 가운데에 위치합니다.

 

<Caps Lock 키 조절>

어떻게 Caps Lock 키를 조절할 수 있습니까?

SetKeyboardState 함수를 사용하면 됩니다.

다음은 버튼을 누를 때 마다 Caps Lock 키의 상태가 변하도록 하는 코드입니다.

procedure TForm1.Button1Click(Sender: TObject);
   var
      Level : Integer;
      KeyState : TKeyBoardState;
      begin
         Level := GetKeyState(VK_CAPITAL); {Caps Lock 키를 체크한다}
         GetKeyboardState(KeyState);
         If Level = 0 then
         begin
            KeyState[VK_CAPITAL] := 1;
            setKeyboardState(KeyState);
        end
        else if Level = 1 then
        begin
           KeyState[VK_CAPITAL] := 0;
         setKeyboardState(KeyState);
   end;
end;

 

<눌려진 Key가 무엇인지 확인하는 방법>

Form의 KeyPreview 속성을 True 로 하고, KeyDown 이벤트에서 처리하면됩니다.

다음은 Key를 처리하는 예제 procedure 입니다.

procedure TForm1.Edit3KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
tempstr: string; {used to spell out keys typed}
begin

{be sure to set Form.KeyPreview to True}
Edit4.Text := '';
if (Shift = ([ssShift])) then Edit4.Text := Edit4.Text + 'Shift';
if (Shift = ([ssShift, ssAlt])) then Edit4.Text := Edit4.Text + 'Shift+Alt';
if (Shift = ([ssShift, ssCtrl])) then Edit4.Text := Edit4.Text + 'Shift+Ctrl';
if (Shift = ([ssShift, ssAlt, ssCtrl])) then Edit4.Text := Edit4.Text +'Shift+Ctrl+Alt';
if (Shift = ([ssAlt])) then Edit4.Text := Edit4.Text + 'Alt';
if (Shift = ([ssAlt, ssCtrl])) then Edit4.Text := Edit4.Text + 'Ctrl+Alt';
if (Shift = ([ssCtrl])) then Edit4.Text := Edit4.Text + 'Ctrl';

tempstr := '';

case Key of
VK_CANCEL: tempstr := 'CANCEL';
VK_BACK: tempstr := 'BACKSPACE';
VK_TAB: tempstr := 'TAB';
VK_CLEAR: tempstr := 'CLEAR';
VK_RETURN: tempstr := 'ENTER';
VK_PAUSE: tempstr := 'PAUSE';
VK_CAPITAL: tempstr := 'CAPS LOCK';
VK_ESCAPE: tempstr := 'ESC';
VK_SPACE: tempstr := 'SPACEBAR';
VK_PRIOR: tempstr := 'PAGE UP';
VK_NEXT: tempstr := 'PAGE DOWN';
VK_END: tempstr := 'END';
VK_HOME: tempstr := 'HOME';
VK_LEFT: tempstr := 'LEFT ARROW';
VK_UP: tempstr := 'UP ARROW';
VK_RIGHT: tempstr := 'RIGHT ARROW';
VK_DOWN: tempstr := 'DOWN ARROW';
VK_SELECT: tempstr := 'SELECT';
VK_EXECUTE: tempstr := 'EXECUTE';
VK_SNAPSHOT: tempstr := 'PRINT SCREEN';
VK_INSERT: tempstr := 'INS';
VK_DELETE: tempstr := 'DEL';
VK_HELP: tempstr := 'HELP';

{VK_1..VK_0 and VK_A..VK_Z are not defined so you have to use the Ord()
function instead which yields the equivilent VK code}

Ord('0'): tempstr := '0';
Ord('1'): tempstr := '1';
Ord('2'): tempstr := '2';
.
.
Ord('A'): tempstr := 'A';
Ord('B'): tempstr := 'B';
Ord('C'): tempstr := 'C';
.
.
VK_NUMPAD0: tempstr := 'Numeric keypad 0';
VK_NUMPAD1: tempstr := 'Numeric keypad 1';
VK_NUMPAD2: tempstr := 'Numeric keypad 2';
.
.
VK_MULTIPLY: tempstr := 'Multiply';
VK_ADD: tempstr := 'Add';
VK_SEPARATOR: tempstr := 'Separator';
VK_SUBTRACT: tempstr := 'Subtract';
VK_DECIMAL: tempstr := 'Decimal';
VK_DIVIDE: tempstr := 'Divide';
VK_F1: tempstr := 'F1';
VK_F2: tempstr := 'F2';
VK_F3: tempstr := 'F3';
.
.
VK_NUMLOCK: tempstr := 'NUM LOCK';
VK_SCROLL: tempstr := 'SCROLL LOCK';
end;
if Edit4.Text = '' then Edit4.Text := tempstr
else if tempstr <> '' then Edit4.Text := Edit4.Text + '+' + tempstr;
Key := 0; {set key to 0 to send no key stroke}
end;

 

<특정 component에서 Enter 키를 눌렀을 때 원하는 처리 추가 방법>

[A8] KeyDown event handler에서 Key가 VK_Return 값인지 체크하면 됩니다.
다음은 그러한 event handler의 간단한 예제입니다.

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_Return then
Edit2.Text := FormatFloat('###.###',StrToFloat(Edit1.Text)) ;
end;

 

<Enter키에 Tab키 효과를 주려면>

Edit 컴포넌트의 OnKeyPress 이벤트에 다음과 같은 코드를 사용하면됩니다.

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
Begin
SelectNext(Sender as TWinControl, True, True );
Key := #0;
end;
end;

이것은 Enter를 Tab처럼 동작하게 합니다. 폼에 있는 전체의 콘트롤(버튼을제외한)에 대해서 이와같은 동작을 원하면 전체의 콘트롤을 선택한 후에 OnKeyPress핸들러를 Edit1KeyPress로 지정하면 됩니다.
이제 각각의 콘트롤에 대해서 Enter가 Tab처럼 작동됩니다.
만약, 폼 레벨에서 이와같은 동작을 원하면(폼에 있는 전체의 콘트롤의 OnKeyPress핸들러에 전부 지정하기를 원하지 않는다면) 폼의 OnKeyPress 에 다음과 같은코드를 사용하면 됩니다. 위의 코드에서 Sender만 ActiveControl로 바꾸고 폼의Property에서 KeyPreview를 true로 바꾸어 주면 됩니다.

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
begin
SelectNext(ActiveControl as TWinControl,True, True );
{Perfome(wm_NextDlgCtl,0,0); 라는 명령문도 가능합니다.}
Key := #0;
end;
end;

이것은 폼에 있는 각각의 콘트롤에 대해서 Enter가 Tab처럼 작동합니다.

 

<Task 전환키인 ALT+TAB 키를 disable 시키려면>

WM_KeyDown message를 처리하거나 Form의 KeyDown event handler를작성합니다.

다음은 간단한 예제 코드입니다.

procedure TForm1.WMKEYDOWN(var Message : TWMKEYDOWN); message WM_KEYDOWN;
begin
if ssAlt in KeyDataToShiftState(Message.KeyData) then
if Message.CharCode = VK_TAB then
begin
Message.CharCode := 0 ;
exit ;
end ;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if ssAlt in Shift then
if Key = VK_TAB then
begin
Key := 0 ;
exit ;
end ;
end;

 

<Keyboard 명령을 사용하여 TForm component에서 스크롤 기능 사용하기>

예를 들어, 폼을 위/아래로 스크롤 하기 위해 PgUp과 PgDn키를 사용하고 싶습니다.

다음과 같이 프로그램 합니다.

procedure TForm1.FormCreate(Sender: TObject);
begin
with VertScrollBar do
begin
Range := 500;
Visible := True;
end;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Const
PageDelta = 100;
Begin
With VertScrollBar do
If Key = VK_NEXT then Position := Position + PageDelta
Else If Key = VK_PRIOR then Position := Position - PageDelta;
End;

주의) TMemo와 같은 component에서는 동작하지 않을 수도 있습니다.

 

<화일 크기를 알고 싶다면>

다음과 같이 프로그램 합니다.

이것은 특정화일의 크기를 에디트박스에 보여주는 예제입니다.

Function FileGetSize(YourFile : String) : LongInt;
Var
   F : Integer;
   Begin
   F:=FileOpen(YourFile,0); { ReadOnly Mode }
   FileGetSize := FileSeek(F,0,2);
   FileClose(F)
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Edit1.Text := IntToStr(FileGetSize('c:\bin\q.exe'));
end;

 

<화일을 복사 하려면>

다음 FileCopy 함수를 사용해 보십시오.

function FileCopy(source,dest: String): Boolean;
var
   fSrc,fDst,len: Integer;
   size: Longint;
   buffer: packed array [0..2047] of Byte;
   begin
      Result := False; { Assume that it WONT work }
      if source <> dest then begin
      fSrc := FileOpen(source,fmOpenRead);
      if fSrc >= 0 then begin
         size := FileSeek(fSrc,0,2);
         FileSeek(fSrc,0,0);
         fDst := FileCreate(dest);
         if fDst >= 0 then begin
         while size > 0 do begin
            len := FileRead(fSrc,buffer,sizeof(buffer));
            FileWrite(fDst,buffer,len);
            size := size - len;
         end;
         FileSetDate(fDst,FileGetDate(fSrc));
         FileClose(fDst);
         FileSetAttr(dest,FileGetAttr(source));
         Result := True;
      end;
      FileClose(fSrc);
   end;
end;
end;

 

<화일의 날짜와 시간을 설정하려면>

SetFTime 함수를 사용합니다.

다음은 화일의 날짜와 시간을 바꾸는 간단한 예제 코드입니다.

var
   f: file;
   begin
      Assign(f, DirInfo.Name);
   Reset(f);
   SetFTime(f, Time);
   Close(f);
end;

 

<INI file을 어떻게 처리합니까>

TIniFile Object를 이용하면 응용프로그램에서 .INI화일을 생성하여조작할 수 있습니다.
중요한 method로는 Create, ReadString, WriteString 등이 있습니다.

다음은 그러한 method 들의 간단한 예제 코드입니다.

var
   IniFile: TIniFile;
   begin
      IniFile := TIniFile.Create('C:\Windows\Delphi.INI');
      IniFile.ReadString('Library', 'SearchPath', 'C:\Delphi\Bin');
      IniFile.WriteString('Library', 'SearchPath', 'C:\Delphi\Bin;C:\MyDir');
      IniFile. Free;
end;

 

<특정 디렉토리에 있는 모든 화일을 다루는 방법>

FindFirst와 FindNext 함수를 사용합니다.

다음은 특정 디렉토리에 있는 화일의 이름과 크기를 보여주는 간단한 예제입니다.

var
   SearchRec: TSearchRec;

procedure TForm1.Button1Click(Sender: TObject);
begin
   FindFirst('c:\dl\bin\*.*', faAnyFile, SearchRec);
   Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) +'bytes in size';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   FindNext(SearchRec);
   Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) +'bytes in size';
end;

 

<인쇄관리자에서 표시되는 인쇄작업의 제목을 주고 싶을때>

다음과 같은 코드를 쓰시면 가능합니다.

Printer.Title := 'your title';

 

<프린터의 인치당 픽셀 구하기>

Windows API 함수인 GetDeviceCaps 을 사용하면 가능합니다.
다음은 에디트박스에 프린터의 가로, 세로 인치당 픽셀을 보여주는 간단한 코드입니다.

procedure TForm1.Button2Click(Sender: TObject);
begin
   Edit1.Text := IntToStr(GetDeviceCaps(Printer.Handle, LogPixelsX));
   Edit2.Text := IntToStr(GetDeviceCaps(Printer.Handle, LogPixelsY));
end;

 

<프린터에 escape 코드를 전달하는 방법>

다음은 삼보 KSSM 모드에서 축소 escape 코드를 사용하는 예제입니다.

procedure TForm1.Button1Click(Sender: TObject);
var
   MyFile: Textfile ;
   s, s1 : string ;
   ff : string ;

begin
   {삼보 KSSM Mode}
   s[0] := #1 ; {축소 지정}
   s[1] := #15 ;
   s1[0] := #1 ; {축소 해제}
   s1[1] := #18 ;
   ff[0] := #1 ; {Form Feed}
   ff[1] := #12 ;

   AssignFile(MyFile,'PRN') ;
   Rewrite(MyFile);
   s := 'Normal font size' + s + 'small font' + s1 + 'Normal font size' +ff ;
   Writeln(MyFile, s);
   System.CloseFile(MyFile);
end;

또는 Windows API 함수 Escape()를 참고 하십시오.

 

<특정 어드레스에 데이타를 저장하려면>

Object Pascal에서는 사용자가 직접 메모리를 다룰 수 있도록 다음과같은 함수를 제공합니다.

Mem
MemW
MemL

Mem의 각 요소는 Byte이고, MemW의 각 요소는 Word이며 MemL의 요소들은 Longint입니다.
Mem 배열함수는 인덱스로 특정한 형식을 취합니다.

다음은 예제 코드입니다:

Mem[$0040:$0049] := 7; {7 을 $0040:$0049에 저장한다}
Data := MemW[Seg(V):Ofs(V)]; {변수 V의 첫 2바이트에 저장된 워드 값을 변수데이타로 옮긴다.}

 

<TPrinter Object를 사용하려면>

다음 예제를 참고하십시오.

var Printer : TPrinter ;

FontDialog1.Font.Assign(Edit1.Font);
if Font1.Dialog.Execute then Edit1.Font.Assign(FontDialog1.Font);

Printer.Canvas.TextOut(X, Y, '문자열');
Printer.Canvas.TextRect(TRect, X, Y, '문자열');
Printer.Canvas.TextHeight('문자열');
GetDeviceCaps(Printer.Handle, LOGPIXELSX);
GetDeviceCaps(Printer.Handle, LOGPIXELSY);

Printer.NewPage;

 

<RES파일 추가후 Resource를 찾지 못할 경우>

사용자가 .RES화일을 추가 했어도 왜 사용자의 프로그램은 Resource의어느것도 찾지 못하는지요? 만약 사용자의 폼에 Unit 이름과 .RES가 같아서그럴까요?

만약 포함된 .RES화일의 이름이 .DPR화일 이름과 같다면 Delphi는자신의 .RES 화일로 덮어쓰기를 할 것입니다. 추가적으로, Project RES 화일은단지 Delphi Project 관리에 대한 것입니다.이 RES 화일에 Resources를 추가하거나,편집할 수 없습 니다.

 

<RC file을 컴파일하는 방법과 Bitmap, Cursor, Icon등을 사용하려면>

DOS Prompt에서 Delphi\Bin directory에 있는 BRCC.EXE를 이용하여컴파일하면 됩니다. 컴파일된 RC file은 .RES 형 태의 binary file로 생성됩니다.
생성된 .RES file을 다음과 같이 선언하여 program에서 사용하면 됩니다.

implementation

{$R C:\Delphi\MyDir\MyRes.Res}

위와같이 선언한 후 사용시에는 Windows API를 이용하면 됩니다.

Image1.Picture.Bitmap.Handle := LoadBitmap(HInstance, 'BITMAP1');
Screen.Cursors[1] := LoadCursor(HInstance, 'CURSOR1');
Image1.Picture.Icon.Handle := LoadIcon(HInstance, 'ICON1');
LoadString(HInstance, 1000, Buffer, 255);

 

<사용자에게 에러를 보여주기 전에 가로채기>

그러한 역할을 하는 새로운 Exception을 다음과 같이 만들 수 있습니다.
다음에 프로시져를 main 폼에 선언해줍니다.

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);

{Exception처리를 하기 위한 procedure를 선언한다}
procedure MyException(Sender:TObject; E:Exception);
private
{ Private declarations }
public
{ Public declarations }
end;

procedure TMyForm.MyException(Sender:TObject; E:Exception);
begin
   if (E.ClassType.ClassName='EConvertError') then
begin
   {사용자가 원하는 처리 내용}
end
else Application.ShowException(E);
end;

procedure TMyForm.FormCreate(Sender: TObject);
begin
   Application.OnException := MyException;
end;

 

<Delphi는 Run-Time 오류를 어떻게 조정합니까>

Delphi에서 Run-Time 오류가 발생할때에 Exception이 생성됩니다.Delphi에서 사용자의 프로그램이 실행되는 동안 Ex ception이 발생할때, 개발환경에서특수한 옵션이 설정된다면, Delphi는 발생한 Line에 커서를 위치시킬 것입니다.그러면서도, 프로그램은 종료되지 않습니다. 따라서 Exception이 생성되면 사용자의어플리케이션은 자동적으로 종료되지 않습니다.

 

<'Stream Read Error'을 조정할 수 있는 방법>

*.DSM을 삭제한후 다시 Project를 컴파일합니다.

 

<WinPrn Unit 컴파일시 에러>

[Q] WinPrn Unit라 불리우는 코드를 컴파일할때, Delphi는 'It can't findWinPrn.DCU'를 나타냅니다.

[A] Option/Project의 search path에 \Delphi\Source\Rtl70'을 추가 합니다.

 

<새로운 커서를 만들어 사용하려면>

다음과 같이 RES 화일을 project에 포함시킵니다.

{$R c:\dl\testcur.res} {RES 화일의 이름과 경로를 명시}

procedure TForm1.Button1Click(Sender: TObject);
Var
   ddd: PChar;
begin
   GetMem(ddd, 8);
   ddd := 'Cursor_1';
   SetClassWord(Form1.handle, GCW_HCURSOR, LoadCursor(hinstance, ddd));
end;

 

<Cursor 모양을 바꾸려면>

다음은 어떤 작업시에 HourGlass 커서를 보여주고, 다시 정상적인커서를 보여주는 예제입니다.

Begin
Try
Screen.Cursor:=crHourGlass;
ReportForm := TReportForm.Create(Application);
Screen.Cursor:=crDefault;
ReportForm.ShowModal;
ReportForm.Free;
Finally
Screen.Cursor:=crDefault;
end;
end;

 

<이미지의 크기를 조절하여 보려주려면>

다음 예제를 참고하십시오.

procedure TForm.ZoomImage;
var Bitmap: TBitmap;
   DstRect: TRect;
begin
      Bitmap := TBitmap.Create;
      Bitmap.Width := { 원하는 길이 }
      Bitmap.Height := { 원하는 높이 }
      Bitmap.Canvas.StretchDraw(Bitmap.Canvas.ClipRect,{원하는 이미지});

      Image1.Picture.Graphic := Bitmap;
      Image1.Invalidate;
end;

 

<아이콘을 Glyphs으로 바꾸려면>

다음을 프로그램 하여 보십시오.

unit Procs;

interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms,StdCtrls, Buttons, ExtCtrls, ShellAPI;

procedure LlenaBoton(boton: TSpeedButton; Programa: string);
procedure LimpiaBoton(boton: TSpeedButton);

var
{Botones de programas}
Pic: TPicture;
Fname : String;
TempFile: array[0..255] of Char;
Icon : TIcon;

implementation
uses ttotro;

procedure LlenaBoton(boton: TSpeedButton; Programa: string);
var
NumFiles, NameLength : integer;
nIconsInFile : word;
rBoton : TRect;
oBitmap : TBitmap;
oBitmap2: TBitmap;
NombreBitmap: string;

begin

try
screen.cursor := crHourglass;

{Extrae el Icono}
Icon := TIcon.Create;
StrPCopy(TempFile, Programa);
Icon.Handle := ExtractIcon(HInstance, TempFile, 0);

{Crea una instancia de TPicture}
Pic := TPicture.Create;
{Asigna el icon.handle a la propiedad Pic.icon}

Pic.Icon := Icon;

{Configura el tamano del bitmap como el del icono y el del segundo bitmapcon el tamano del boton}
oBitmap := TBitMap.create;
oBitmap2 := TBitMap.create;
oBitmap2.Width := Icon.Width;
oBitmap2.Height := Icon.Height;
oBitmap.Width := boton.Width-4;
oBitmap.Height := boton.Height-4;

{ Dibuja el icono en el bitmap }
oBitmap2.Canvas.Draw( 0, 0, Pic.Graphic );
rBoton.left := 1;
rBoton.Top := 1;
rBoton.right:= boton.Width-6;
rBoton.Bottom := boton.Height-6;
oBitmap.Canvas.StretchDraw(rBoton, oBitmap2);

Boton.Hint := Programa;

NombreBitmap := Copy(programa, 1, Length(programa)-3)+'BMP';
{Salva el bitmap en un fichero}
If Not FileExists(NombreBitmap) Then
begin
oBitmap.SaveToFile(ExtractFilePath(Application.ExeName)+ExtractFileName(NombreBitmap));
Boton.Glyph := oBitmap;
end
else
{Carga el BMP en el boton}
Boton.Glyph.LoadFromFile(ExtractFilePath(Application.ExeName)+ExtractFileName(NombreBitmap));

finally
Icon.Free;
oBitmap.Free;
oBitmap2.Free;
screen.cursor := crDefault;
end;
end;

procedure LimpiaBoton(boton: TSpeedButton);
var
oBitmap : TBitmap;
rBoton : TRect;
begin

try
{Configuara el tamano del bitmap como el del icono y el del segundo
bitmap con el tamano del boton}
oBitmap := TBitMap.create;
oBitmap.Width := boton.Width-4;
oBitmap.Height := boton.Height-4;
Boton.Glyph := oBitmap;
finally
oBitmap.Free;
end;
end;

end.

 

<image component에 특정 application의 icon을 보이게 하는 방법>

Windows API인 ExtractIcon function을 이용하면 됩니다.

uses SHELLAPI;

Image1.Picture.Icon.Handle := ExtractIcon(Handle, 'C:\Delphi\Bin\Delphi.exe',0);

 

<날짜와 시간의 형식을 DD/MM/YY 에서 DDMMYYYY 로 바꾸려면>

다음 예제를 참고하십시오.

LongDate := FormatDateTime('ddmmyyyy', StrToDate(ShortDate));

위의 코드는 DD/MM/YY 와 같은 제어판의 날짜 형식을 형식문자열(여기서는 DDMMYYYY)로바꾸어줍니다.

 

<Date 또는 시간차이 구하는 법>

다음은 시간차이를 구하는 예제입니다.

procedure TForm1.MaskEdit2Exit(Sender: TObject);
begin
   MaskEdit2.Text := FormatDateTime('HH:MM', StrToTime(MaskEdit2.Text));
   Edit2.Text := FormatDateTime('HHMM', StrToTime(MaskEdit2.Text));
   if StrToTime(MaskEdit2.text) < StrToTime(MaskEdit1.text) then
      ShowMessage('From 시간보다 작습니다.')
   else
      MaskEdit3.Text := FormatDateTime('HH:MM', StrToTime(MaskEdit2.text) - StrToTime(MaskEdit1.text));
end;

다음은 날짜차이를 구하는 예제입니다.

procedure TForm1.MaskEdit5Exit(Sender: TObject);
begin
   MaskEdit5.Text := FormatDateTime('YYYY-MM-DD', StrToDate(MaskEdit5.Text));
   Edit5.Text := FormatDateTime('MMDDYYYY', StrToDate(MaskEdit5.Text));
   if StrToDate(MaskEdit5.text) < StrToDate(MaskEdit4.text) then
      ShowMessage('From 날짜보다 작습니다.')
   else begin
      MaskEdit6.Text := FormatDateTime('YYYY-MM-DD', StrToDate(MaskEdit5.text)- StrToDate(MaskEdit4.text));
      Edit6.Text := FloatToStr(StrToDate(MaskEdit5.text) - StrToDate(MaskEdit4.text));
   end;
end;

 

<number를 천단위로 분리해서 comma를 찍어주는 방법>

다음과 같이 하면 됩니다.

function FormatNumber(l: longint): string;
begin
   FormatNumber := FormatFloat('#,##0', StrToFloat(IntToStr(l)));
end;

 

<Application에서 사용되는 날짜형식을 특정한 format으로 고정하는 방법>

SysUtils Unit에 선언된 변수들을 원하는 특정값으로 주면 됩니다.
Application 전체에 원하는 형태로 날짜 format을 지정하려면 main form의 onCreateEvent에 다음과 같이 하면 됩니다.

ShortDateFormat := 'YY-MM-DD';
LongDateFormat := 'YYYY-MM-DD';

 

<윈도우/대화상자의 크기를 재지정 했을때, 버튼을 윈도우내의 하단에 자동적으로 정렬할 수 있는 방법>

TPanel을 생성한후, TPanel의 Align특성을 사용하여 하단에 정렬하십시오.
그리고 나서 이 Panel 위에 버튼을 위치 시키면 됩니다. 만약 Button만 나타내고싶은 경우 Panel의 특성중 Ctl3D를 'Off'로 설 정하시고, Bevels를 none' 으로Parentcolor를 True로 설정하면 됩니다.

 

<파라독스의 계산 필드에서 25.55 가 24.499999 가 되는 이유>

숫자의 소수점 자리수가 틀리면 그러한 잘못된 값을 줍니다.
다음과 같이 Round 함수나 str함수를 써서 자리수를 맞춰서 계산하시기 바랍니다.

SalesIncVAT:=round(SalesIncVAT*100)/100; {소숫점 둘째자리 수}

혹은

var
s : string;
begin
str(SalesIncVat:10:2,s); {10 자리수와 소수점 둘째짜리}
Label1.Caption:=s;
end ;

 

<금주가 몇번째 주인지 구하는 법 (윤년 계산법)>

다음 함수를 사용해 보십시오.

윤년을 계산하는 함수 :
function kcIsLeapYear( nYear: Integer ): Boolean;
begin
Result := (nYear mod 4 = 0) and ((nYear mod 100 <> 0) or (nYear mod
400 = 0));
end;


한달에 몇일이 있는지를 계산하는 함수 :
function kcMonthDays( nMonth, nYear: Integer ): Integer;
const
DaysPerMonth: array[1..12] of Integer = (31, 28, 31, 30, 31, 30, 31, 31,30, 31, 30, 31);
begin
Result := DaysPerMonth[nMonth];
if (nMonth = 2) and kcIsLeapYear(nYear) then Inc(Result);
end;


위의 두 함수를 써서 몇번째 주인지 계산하는 함수 :
function kcWeekOfYear( dDate: TDateTime ): Integer;
var
X, nDayCount: Integer;
nMonth, nDay, nYear: Word;
begin

nDayCount := 0;
deCodeDate( dDate, nYear, nMonth, nDay );
For X := 1 to ( nMonth - 1 ) do
nDayCount := nDayCount + kcMonthDays( X, nYear );

nDayCount := nDayCount + nDay;
Result := ( ( nDayCount div 7 ) + 1 );
end;

 

<Hint가 나타나는 속도를 빠르게 하는 방법>

TApplication의 property중 HintPause property를 이용하면 됩니다.기본값은 800 millisecond 입니다.

Application.HintPause := 100;

 

<실행중 Component를 생성하고 property를 주려면>

다음의 코드를 참고하십시오.

{component를 만듭니다.}
procedure TForm1.Button1Click(Sender: TObject);
begin
   SomeComponent:= TComponentClass(FindClass(Edit1.Text)).Create(Self);
   (SomeComponent as TControl).Parent := Self;
end;

{만들 수 있는 component의 유형}
procedure TForm1.FormCreate(Sender: TObject);
begin
   RegisterClasses([TButton, TEdit, TMemo, TLabel]);
end;

{component의 property를 주는 방법}
procedure TForm1.Button2Click(Sender: TObject);
var
   PropType: pTypeInfo;
   PropInfo: pPropInfo;
begin
   PropInfo := GetPropInfo(SomeComponent.ClassInfo, Edit2.Text);
   PropType := PropInfo^.PropType;
   case PropType^.Kind of
      tkInteger:
      SetOrdProp(SomeComponent, PropInfo,StrToInt(Edit3.Text));
      tkChar:
      SetOrdProp(SomeComponent, PropInfo, Ord(Edit3.Text[1]));
      tkEnumeration:
      SetOrdProp(SomeComponent, PropInfo, GetEnumValue(PropType,Edit3.Text));
      tkFloat:
      SetFloatProp(SomeComponent, PropInfo,StrToFloat(Edit3.Text));
      tkString:
      SetStrProp(SomeComponent, PropInfo, Edit3.Text);
   end;
end;

 

<실행 중 만든 컴포넌트에 설정한 기본값이 설정되지 않은 경우>

[Q] 실행중에 component 하나를 만들었습니다. 그런데 제가 사용한 기본값이 설정되지 않은 것 같습니다. 어떻게 해야 합니까?

[A] 그 component의 Create constructor에서 property의 기본값을 설정했는지 확인하십시오. 기존 property의 기본값은 실행중에 만든 component에는 적용되지않습니다.

 

<Run-Time시에 VCL 컴포넌트의 개체를 생성하려면>

다음의 코드는 Runtime시에 Form을 생성하는 것입니다.

with TPasswordForm.Create(Application) do
Begin { i.e TForm1, TPasswordForm etc. }
ShowModal; { Diaplay form as a modal window }
Free; { Free the form when it is closed }
end;

다음의 코드는 Button을 생성하는 것입니다.

Var
TempButton : TButton; {This is only a pointer to a TButton }
Begin
TempButton := TButton.Create(Self);
TempButton.Parent := Self; { Must assign the Parent }
TempButton.Caption := 'Run-time';{ Assign properties new }
TempButton.Visible := True; { Show to button }
End;

이 개체는 사용후에 반드시 Free 시켜야 합니다.

 

<'Tab Order 설정방법>

Control을 정하기위해 Form에서 클릭한후 Object Inspector에서 TabOrderproperty를 설정해 줍니다.

 

<이름에 의해서 component를 access 하기>

FindComponent method를 사용하면 됩니다.

for I := 1 to 10 do
with Form1.FindComponent('SpeedButton' + IntToStr(i)) as TSpeedButton do
Enabled := False;

 

<Lasso 제어>

다음을 참고하십시오.

1. 폼의 OnMouseDown 이벤트:
bMarquee := True; {bMarquee는 Boolean변수}
ptOrigin := Point( X, Y );
ptMove := Point( X, Y );{ptOrigin, ptMove는 Point변수}

Canvas.Pen.Color := clBlack;
Canvas.Pen.Width := 1;
Canvas.Pen.Style := psDash;
Brush.Style := bsClear;

DrawMarquee(ptOrigin, ptMove, pmNotXor );

2. 폼의 OnMouseMove 이벤트
if bMarquee = True then begin
   DrawMarquee(ptOrigin, ptMove, pmNotXor );
   DrawMarquee(ptOrigin, Point( X, Y ), pmNotXor );
   ptMove := Point( X, Y );
   Canvas.Pen.Mode := pmCopy;
end;

3. 폼의 OnMouseUp 이벤트
if bMarquee = True then begin
   bMarquee := False;
   DrawMarquee(ptOrigin, Point( X, Y ), pmNotXor );
   ptMove := Point( X, Y );
end;

4. DrawMarquee procedure

procedure myForm.DrawMarquee( mStart, mStop : TPoint; AMode : TPenMode);
begin
   Canvas.Pen.Mode := AMode;
   Canvas.Rectangle( mStart.X, mStart.Y, mStop.X, mStop.Y );
end;

 

<inline Assembler 코드를 사용하려면>

다음은 시스템의 시간을 맞추는 예제입니다.

procedure TForm1.Button1Click(Sender: TObject);
begin
   {set system time}
   asm
      mov Ah,2dh { function number}
      mov ch,1 { hours }
      mov cl,10 { minutes }
      mov dx,0 { seconds }
      INT 21h
   end ;
end;

 

'Delphi' 카테고리의 다른 글

날짜/시간형식 변경 및 강제 시간세팅  (0) 2014.02.13
Q&A 정리  (0) 2014.02.13
올림 / 내림(버림)  (0) 2011.08.03
델파이의 소숫점 반올림 방식  (2) 2011.08.03
동적 체크박스 생성  (0) 2010.03.24