본문 바로가기

Dev.../델파이4의 모든것

델파이4의모든것에 들어있던 팁모음집…

팁모음집

금주가 몇번째 주인지 어떻게 구합니까

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;

긴 파일명 사용하기

function fileLongName(const aFile: String): String;

var

aInfo: TSHFileInfo;

begin

if SHGetFileInfo(PChar(aFile),0,aInfo,Sizeof(aInfo),SHGFI_DISPLAYNAME)<>0 then

Result:=StrPas(aInfo.szDisplayName)

else

Result:=aFile;

end;

네트워크 검색

connections or persistent (won't normally get here):}

r:=WNetOpenEnum(ListType,ResourceType,RESOURCEUSAGE_CONTAINER, nil,hEnum);

{ Couldn't enumerate through this container; just make a note of it and continue on: }

if r<>NO_ERROR then

begin

AddShareString(TopContainerIndex,'');

WNetCloseEnum(hEnum);

Exit;

end;

{ We got a valid enumeration handle; walk the resources: }

while (1=1) do

begin

EntryCount:=1;

NetResLen:=SizeOf(NetRes);

r:=WNetEnumResource(hEnum,EntryCount,@NetRes,NetResLen);

case r of

0: begin

{ Yet another container to enumerate; call this function recursively to handle it: }

if (NetRes[0].dwUsage=RESOURCEUSAGE_CONTAINER) or (NetRes[0].dwUsage=10) then

DoEnumerationContainer(NetRes[0])

else

case NetRes[0].dwDisplayType of

{ Top level type: }

RESOURCEDISPLAYTYPE_GENERIC,

RESOURCEDISPLAYTYPE_DOMAIN,

RESOURCEDISPLAYTYPE_SERVER: AddContainer(NetRes[0]);

{ Share: }

RESOURCEDISPLAYTYPE_SHARE: AddShare(TopContainerIndex,NetRes[0]);

end;

end;

ERROR_NO_MORE_ITEMS: Break;

else begin

MessageDlg('Error #'+IntToStr(r)+' Walking Resources.',mtError,[mbOK],0);

Break;

end;

end;

end;

{ Close enumeration handle: }

WNetCloseEnum(hEnum);

end;

procedure TfrmMain.FormShow(Sender: TObject);

begin

DoEnumeration;

end;

// Add item to tree view; indicate that it is a container:

procedure TfrmMain.AddContainer(NetRes: TNetResource);

var

ItemName: String;

begin

ItemName:=Trim(String(NetRes.lpRemoteName));

if Trim(String(NetRes.lpComment))<>'' then

begin

if ItemName<>'' then ItemName:=ItemName+' ';

ItemName:=ItemName+'('+String(NetRes.lpComment)+')';

end;

tvResources.Items.Add(tvResources.Selected,ItemName);

end;

// Add child item to container denoted as current top:

procedure TfrmMain.AddShare(TopContainerIndex: Integer; NetRes:TNetResource);

var

ItemName: String;

begin

ItemName:=Trim(String(NetRes.lpRemoteName));

if Trim(String(NetRes.lpComment))<>'' then

begin

if ItemName<>'' then ItemName:=ItemName+' ';

ItemName:=ItemName+'('+String(NetRes.lpComment)+')';

end;

tvResources.Items.AddChild(tvResources.Items[TopContainerIndex],ItemName);

end;

{ Add child item to container denoted as current top;

this just adds a string for purposes such as being unable to enumerate a container. That is, the container's shares are not accessible to us.}

procedure TfrmMain.AddShareString(TopContainerIndex: Integer;ItemName: String);

begin

tvResources.Items.AddChild(tvResources.Items[TopContainerIndex],ItemName);

end;

{ Add a connection to the tree view.

Mostly used for persistent and currently connected resources to be displayed.}

procedure TfrmMain.AddConnection(NetRes: TNetResource);

var

ItemName: String;

begin

ItemName:=Trim(String(NetRes.lpLocalName));

if Trim(String(NetRes.lpRemoteName))<>'' then

begin

if ItemName<>'' then ItemName:=ItemName+' ';

ItemName:=ItemName+'-> '+Trim(String(NetRes.lpRemoteName));

end;

tvResources.Items.Add(tvResources.Selected,ItemName);

end;

// Expand all containers in the tree view:

procedure TfrmMain.mniExpandAllClick(Sender: TObject);

begin

tvResources.FullExpand;

end;

// Collapse all containers in the tree view:

procedure TfrmMain.mniCollapseAllClick(Sender: TObject);

begin

tvResources.FullCollapse;

end;

// Allow saving of tree view to a file:

procedure TfrmMain.mniSaveToFileClick(Sender: TObject);

begin

if dlgSave.Execute then

tvResources.SaveToFile(dlgSave.FileName);

end;

// Allow loading of tree view from a file:

procedure TfrmMain.mniLoadFromFileClick(Sender: TObject);

begin

if dlgOpen.Execute then

tvResources.LoadFromFile(dlgOpen.FileName);

end;

// Rebrowse:

procedure TfrmMain.btnOKClick(Sender: TObject);

begin

DoEnumeration;

end;

end.

네트워크 드라이브 등록하기

procedure TStartForm.NetBtnClick(Sender: TObject);

var

OldDrives: TStringList;

i: Integer;

begin

OldDrives := TStringList.Create;

OldDrives.Assign(Drivebox.Items); // Remember old drive list

// Show the connection dialog

if WNetConnectionDialog(Handle, RESOURCETYPE_DISK) = NO_ERROR then

begin

DriveBox.TextCase := tcLowerCase; // Refresh the drive list box

for i := 0 to DriveBox.Items.Count - 1 do

begin

if Olddrives.IndexOf(Drivebox.Items[i]) = -1 then

begin // Find new Drive letter

DriveBox.ItemIndex := i; // Updates the drive list box to new drive letter

DriveBox.Drive := DriveBox.Text[1]; // Cascades the update to connected directory lists, etc

end;

end;

DriveBox.SetFocus;

end;

다른 윈도우에서 선택된 문자열 복사하기

procedure TForm1.WMHotkey(Var msg: TWMHotkey);

var

hOtherWin,

hFocusWin: THandle;

OtherThreadID, ProcessID: DWORD;

begin

hOtherWin := GetForegroundWindow;

if hOtherWin = 0 then

Exit;

OtherThreadID := GetWindowThreadProcessID( hOtherWin, @ProcessID );

if AttachThreadInput( GetCurrentThreadID, OtherThreadID, True ) then

begin

hFocusWin := GetFocus;

if hFocusWin <> 0 then

try

SendMessage( hFocusWin, WM_COPY, 0, 0 );

finally

AttachThreadInput( GetCurrentThreadID, OtherThreadID, False );

end;

end;

Memo1.Lines.Add( Clipboard.AsText );

if IsIconIC( Application.Handle ) then

Application.Restore;

end;

다른 Application에 Data전달하기

WM_COPYDATA-다른 Application에 Data전달

unit other_ap;

{다른 Application을 찾아서 WM_COPYDATA로 DATA를 전달 }

interface

uses

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

const WM_COPYDATA = $004A;

type

Tform1 = class(TForm)

Button1: TButton;

Memo1: TMemo;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

procedure WMCopyData(var m : TMessage); message WM_COPYDATA;

public

{ Public declarations }

end;

var

form1: Tform1;

implementation

{$R *.DFM}

type

PCopyDataStruct = ^TCopyDataStruct;

TCopyDataStruct = record

dwData: LongInt;

cbData: LongInt;

lpData: Pointer;

end;

type

PRecToPass = ^TRecToPass;

TRecToPass = packed record

s : string[255];

i : integer;

end;

procedure TForm1.WMCopyData(var m : TMessage);

begin

Memo1.Lines.Add(PRecToPass(PCopyDataStruct(m.LParam)^.lpData)^.s);

Memo1.Lines.Add(IntToStr(PRecToPass(PCopyDataStruct(m.LParam)^.lpData)^.i));

end;

procedure Tform1.Button1Click(Sender: TObject);

var

h : THandle;

cd : TCopyDataStruct;

rec : TRecToPass;

begin

if Form1.Caption = 'My App' then

begin

h := FindWindow(nil, 'My Other App');

rec.s := 'Hello World - From My App';

rec.i := 1;

end

else

begin

h := FindWindow(nil, 'My App');

rec.s := 'Hello World - From My Other App';

rec.i := 2;

end;

cd.dwData := 0;

cd.cbData := sizeof(rec);

cd.lpData := @rec;

if h <> 0 then

SendMessage(h, WM_CopyData, Form1.Handle, LongInt(@cd));

end;

end.

델파이 중복실행방지

 unit PrevInst;

 interface

 uses

  WinTypes, WinProcs, SysUtils;

 type

  PHWND = ^HWND;

  function EnumFunc(Wnd:HWND; TargetWindow:PHWND): bool; export;

  procedure GotoPreviousInstance;

 implementation

  function EnumFunc(Wnd:HWND; TargetWindow:PHWND): bool;

  var

    ClassName : array[0..30] of char;

  begin

    Result := true;

    if GetWindowWord(Wnd,GWW_HINSTANCE) = hPrevInst then

    begin

      GetClassName(Wnd,ClassName,30);

      if StrIComp(ClassName,'TApplication') = 0 then

      begin

        TargetWindow^ := Wnd;

        Result := false;

      end;

    end;

  end;

  procedure GotoPreviousInstance;

  var

    PrevInstWnd : HWND;

  begin

    PrevInstWnd := 0;

    EnumWindows(@EnumFunc,longint(@PrevInstWnd));

    if PrevInstWnd <> 0 then

      if IsIconic(PrevInstWnd) then

        ShowWindow(PrevInstWnd, SW_RESTORE)

      else

        BringWindowToTop(PrevInstWnd);

  end;

end.

  이러한 유닛을 프로젝트에 추가 하신후 DPR 소스의 BEGIN - END를 다음과 같이

  수정해 주세요

begin

  if hPrevInst <> 0 then

    GotoPreviousInstance

  else

  begin

    Application.CreateForm(MyForm, MyForm);

    Application.Run;

  end;

end.

델파이에서 한글 토글하기

델파이 2.0이하에서는

ims.pas를 이용하여 한영토글을 구현했는데,

3.0이상 에서는 한영토글에 대한 간단한 답에 있더군요.

TEdit에 ImsMode 프라퍼티를 이용합니다.

edit1.ImeMode:=imHangul; //한글모드

edit2.ImeMode:=imAlpha; //영문모드

입력이 한글이 많을 경우,

입력 초기모드를 한글모드로 바꿔준다면,

사용자의 한/영키를 누르는 것을 없애줄 수 있겠지요.

델파이에서 자동으로 한글입력모드로 변경시키는 소스

uses절에 Imm을 추가하세요

그런다음 아래 프로시저를 작성하여 OnEnter 이벤트에서

한글을 on하시구요 OnExit 이벤트에서 off하세요

procedure TForm1.SetHangeulMode(SetHangeul: Boolean);

var

  tMode : HIMC;

begin

  tMode := ImmGetContext(handle);

  if SetHangeul then  // 한글모드로

    ImmSetConversionStatus(tMode, IME_CMODE_HANGEUL,      IME_CMODE_HANGEUL)

  else                // 영문모드로

    ImmSetConversionStatus(tMode, IME_CMODE_ALPHANUMERIC,

IME_CMODE_ALPHANUMERIC);

end;

델파이에서 폼을 사정없이 뜯어내는 방법의 소스

var

WindowRgn,HoleRgn : HRgn;

begin

WindowRgn := 0;

GetWindowRgn(handle, WindowRgn);

DeleteObject(WindowRgn);

WindowRgn := CreateRectRgn(0,0,Width,Height);

HoleRgn := CreateRectRgn(16,25,126,236);

CombineRgn(WindowRgn, WindowRgn, HoleRgn, RGN_DIFF);

SetWindowRgn(handle, WindowRgn, TRUE);

DeleteObject(HoleRgn);

end;

델파이에서의 키값

아래에 가상키 값 리스트입니다....

vk_LButton = $01;

vk_RButton = $02;

vk_Cancel = $03;

vk_MButton = $04; { NOT contiguous with L & RBUTTON }

vk_Back = $08;

vk_Tab = $09;

vk_Clear = $0C;

vk_Return = $0D;

vk_Shift = $10;

vk_Control = $11;

vk_Menu = $12;

vk_Pause = $13;

vk_Capital = $14;

vk_Escape = $1B;

vk_Space = $20;

vk_Prior = $21;

vk_Next = $22;

vk_End = $23;

vk_Home = $24;

vk_Left = $25;

vk_Up = $26;

vk_Right = $27;

vk_Down = $28;

vk_Select = $29;

vk_Print = $2A;

vk_Execute = $2B;

vk_SnapShot = $2C;

{ vk_Copy = $2C not used by keyboards }

vk_Insert = $2D;

vk_Delete = $2E;

vk_Help = $2F;

{ vk_A thru vk_Z are the same as their ASCII equivalents: 'A' thru 'Z' }

{ vk_0 thru vk_9 are the same as their ASCII equivalents: '0' thru '9' }

vk_NumPad0 = $60;

vk_NumPad1 = $61;

vk_NumPad2 = $62;

vk_NumPad3 = $63;

vk_NumPad4 = $64;

vk_NumPad5 = $65;

vk_NumPad6 = $66;

vk_NumPad7 = $67;

vk_NumPad8 = $68;

vk_NumPad9 = $69;

vk_Multiply = $6A;

vk_Add = $6B;

vk_Separator = $6C;

vk_Subtract = $6D;

vk_Decimal = $6E;

vk_Divide = $6F;

vk_F1 = $70;

vk_F2 = $71;

vk_F3 = $72;

vk_F4 = $73;

vk_F5 = $74;

vk_F6 = $75;

vk_F7 = $76;

vk_F8 = $77;

vk_F9 = $78;

vk_F10 = $79;

vk_F11 = $7A;

vk_F12 = $7B;

vk_F13 = $7C;

vk_F14 = $7D;

vk_F15 = $7E;

vk_F16 = $7F;

vk_F17 = $80;

vk_F18 = $81;

vk_F19 = $82;

vk_F20 = $83;

vk_F21 = $84;

vk_F22 = $85;

vk_F23 = $86;

vk_F24 = $87;

vk_NumLock = $90;

vk_Scroll = $91;

디렉토리에 관련된 함수

function GetCurrentDir: string; // 현재의 Directory

function ExtractFileDir(const FileName: string): string;

// Directory 만 Return .Filename 빼고

function ExtractFileName(const FileName: string): string;

// 화일 이름만 Return

동작중인 프로그램 죽이기

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, StdCtrls, TlHelp32;

type

TForm1 = class(TForm)

ListBox1: TListBox;

B_Search: TButton;

B_Terminate: TButton;

procedure B_SearchClick(Sender: TObject);

procedure B_TerminateClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

// kernel32.dll을 사용하여 현재 떠있는 process를 읽어온다

procedure Process32List(Slist: TStrings);

var

Process32: TProcessEntry32;

SHandle: THandle; // the handle of the Windows object

Next: BOOL;

begin

Process32.dwSize := SizeOf(TProcessEntry32);

SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if Process32First(SHandle, Process32) then

begin

// 실행화일명과 process object 저장

Slist.AddObject(Process32.szExeFile, TObject(Process32.th32ProcessID));

repeat

Next := Process32Next(SHandle, Process32);

if Next then

Slist.AddObject(Process32.szExeFile, TObject(Process32.th32ProcessID));

until not Next;

end;

CloseHandle(SHandle); // closes an open object handle

end;

procedure TForm1.B_SearchClick(Sender: TObject);

begin

// 현재 실행중인 process를 검색

ListBox1.Items.Clear;

Process32List(ListBox1.Items);

end;

procedure TForm1.B_TerminateClick(Sender: TObject);

var

hProcess: THandle;

ProcId: DWORD;

TermSucc: BOOL;

begin

// 현재 실행중인 process를 kill

if ListBox1.ItemIndex < 0 then System.Exit;

ProcId := DWORD(ListBox1.Items.Objects[ListBox1.ItemIndex]);

// 존재하는 process object의 handle을 return한다

hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcId);

if hProcess = NULL then

ShowMessage('OpenProcess error !');

// 명시한 process를 강제 종료시킨다

TermSucc := TerminateProcess(hProcess, 0);

if TermSucc = FALSE then

ShowMessage('TerminateProcess error !')

else

ShowMessage(Format('Process# %x terminated successfully !', [ProcId]));

end;

end.

레지스트리를 이용한 모뎀찾기

WRegistry := TRegistry.Create;

with Wregistry do

begin

rootkey := HKEY_LOCAL_MACHINE;

if OpenKey

('\System\CurrentControlSet\Services\Class\Modem\0000',False) then

Showmessage ('모뎀이 있습니다.');

...

free..

end;

마우스의 Enter/Exit Event사용하기

TForm1 = class(TForm)

Image1 : TImage;

private

m_orgProc : TWndMethod;

procedure ImageProc ( var Msg : TMessage ) ;

public

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

end;

:

:

procedure TForm1.FormCreate(Sender:TObject);

begin

m_orgProc := Image1.WindowProc;

Image1.WindowProc := ImageProc;

end;

procedure TForm1.FormDestroy(Sender:TObject);

begin

Image1.WindowProc := m_orgProc;

end;

procedure TForm1.ImageProc( var Msg : TMessage );

begin

case Msg.Msg of

CM_MOUSELEAVE:

begin

// 여기서 콘트롤에 마우스가 들어왔을 때를 처리합니다.

end;

CM_MOUSEENTER:

begin

// 여기서 콘트롤로부터 마우스가 벗어날때 부분을 처리합니다.

end;

end;

m_orgProc(Msg);

end;

end;

마우스의 범위 제한하기

다음 예제는 폼에 2개의 버튼을 두고 첫번째 버튼을 누르면 마우스가 폼 밖으로 못나가게 하고, 두번째 버튼을 누르면 원래대로 바꿔주는 프로그램입니다...

procedure TForm1.Button1Click(Sender: TObject);

var

Rect : TRect;

begin

Rect := BoundsRect;

InflateRect(Rect, 0, 0);

ClipCursor(@Rect);

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

ClipCursor(nil);

end;

Message박스에 두줄출력하기

MessageDlg('문자열' + chr(13) + '문자열', mtInformation,[mbOK], 0);

참고 : 윈도우에서는 3줄까지 가능함. 3줄 이상의 문자열은 자동으로 정렬하지

않으니 개발자가 주의해야 함.

바탕화면 바꾸기

  GetMem( ThePChar , 255 );

  StrPCopy( ThePChar , 'wallpaper.bmp');

  SystemParametersInfo( SPI_SETDESKWALLPAPER , 0 ,

                        ThePChar , SPIF_SENDWININICHANGE );

  Freemem( ThePChar , 255 );

브라우저 동작하기

UrlMon 유닛으로 선언되고 있다 HlinkNavigateString Win32 API 을(를) 씁니다.

호출 예:

HlinkNavigateString(Nil,'http://www.borland.co.jp/');

만약 액티브 폼의 중(안)에서 불러내고 싶는 경우에는 이하와 같이 지정합니다:

HlinkNavigateString(ComObject,'http://www.borland.co.jp/');

ShellApi 유닛으로 선언되고 있다 ShellExecute 을(를) 쓰는 것도 가능합니다.

ShellExecute(0, 'open', 'http://www.borland.co.jp/', nil, nil, SW_SHOW)

사용자가 조합키를 누른것처럼 처리하는 방법

다음 소스를 참고하기 바랍니다. 중요한 부분은 조합키중 키와 키, 키와 같이 홀드(hold) 상태인 키를 확인해서 키값을 포스팅해 주는 것입니다.

완전하다면 더할나위 없이 좋겠지만, 그냥 자신의 프로그램에 덧붙여 사용하거나 외부 참조로 사용해도 무방할 것입니다.

procedure PostKeyEx( hWindow: HWnd; key: Word; Const shift: TShiftState; Specialkey: Boolean );

type

TBuffers = Array [0..1] of TKeyboardState;

var

pKeyBuffers : ^TBuffers;

lparam: LongInt;

begin

if IsWindow( hWindow ) then

begin

pKeyBuffers := nil;

lparam := MakeLong( 0, MapVirtualKey( key, 0 ) );

if Specialkey then

lparam := lparam or $1000000;

New( pKeyBuffers );

try

GetKeyboardState( pKeyBuffers^[1] );

FillChar( pKeyBuffers^[0],Sizeof( TKeyboardState ), 0 );

if ssShift In shift then

pKeyBuffers^[0][VK_SHIFT] := $80;

if ssAlt In shift then

begin

pKeyBuffers^[0][VK_MENU] := $80;

lparam := lparam or $20000000;

end;

if ssCtrl in shift then

pKeyBuffers^[0][VK_CONTROL] := $80;

if ssLeft in shift then

pKeyBuffers^[0][VK_LBUTTON] := $80;

If ssRight in shift then

pKeyBuffers^[0][VK_RBUTTON] := $80;

if ssMiddle in shift then

pKeyBuffers^[0][VK_MBUTTON] := $80;

SetKeyboardState( pKeyBuffers^[0] );

if ssAlt in shift then

begin

PostMessage( hWindow, WM_SYSKEYDOWN, key, lparam);

PostMessage( hWindow, WM_SYSKEYUP, key, lparam or $C0000000);

end

else

begin

PostMessage( hWindow, WM_KEYDOWN, key, lparam);

PostMessage( hWindow, WM_KEYUP, key, lparam or $C0000000);

end;

Application.ProcessMessages;

SetKeyboardState( pKeyBuffers^[1] );

finally

if pKeyBuffers <> nil then

Dispose( pKeyBuffers );

end;

end;

end; { PostKeyEx }

procedure TForm1.SpeedButton2Click(Sender: TObject);

Var

W: HWnd;

begin

W := Memo1.Handle;

PostKeyEx( W, VK_END, [ssCtrl, ssShift], False );

// 전체 선택

PostKeyEx( W, Ord('C'), [ssCtrl], False );

// 클립보드로 복사

PostKeyEx( W, Ord('C'), [ssShift], False );

// "C"로 치환

PostKeyEx( W, VK_RETURN, [], False );

// 엔터키(새라인)

PostKeyEx( W, VK_END, [], False );

// 라인의 끝으로

PostKeyEx( W, Ord('V'), [ssCtrl], False );

// 붙여넣기

end;

시스템 About사용하기

ShellAbout(Self.Handle,

PChar(Application.Title),

'http://home.t-online.de/home/mirbir.st/'#13#10'mailto:mirbir.st@t-online.de',

Application.Icon.Handle);

Self.Handle은 현재 동작중인 Application의 실행영역을 리턴하는 것이고....

PChar( Application.Title )은 Title의 Caption을 전달하는 것..

'문서영역'은 이 곳에서 만들었다는 표시...

Application.Icon.Handle은 About에서 보일 Icon의 값을 전달하는 방법

시스템 Image를 사용하는 TListView

procedure TDirTreeView.FindAllSubDirectories(pNode: TCTreeNode; ItsTheFirstPass: Boolean);

var

srch: TSearchRec;

DOSerr: integer;

NewText: String;

NewPath: string;

tNode: TCTreeNode;

cNode: TCTreeNode;

ImagesHandleNeeded : boolean;

cCursor: HCursor;

NewList: TStringList;

i: integer;

tpath: string;

function TheImage(FileID: string; Flags: DWord; IconNeeded: Boolean): Integer;

var

SHFileInfo: TSHFileInfo;

begin

Result := SHGetFileInfo(pchar(FileID), 0,

SHFileInfo, SizeOf(SHFileInfo),

Flags);

if IconNeeded then

Result := SHFileInfo.iIcon;

end;

function ItHasChildren(const fPath: string): Boolean;

var

srch: TSearchrec;

found: boolean;

DOSerr: integer;

begin

chdir(fPath);

Found := false;

DOSerr := FindFirst('*.*',faDirectory,srch);

while (DOSerr=0) and not(Found) do

begin

found := ((srch.attr and faDirectory)=faDirectory)

and ((srch.name<>'.')

and (srch.name<>'..'));

if not(found) then

DOSerr := FindNext(srch);

end;

sysutils.FindClose(srch);

chdir('..');

Result := Found;

end;

begin

tNode := TopItem;

cCursor := Screen.cursor;

Screen.cursor := crHourGlass;

Items.BeginUpdate;

SortType := stNone;

tpath := uppercase(fCurrentPath);

NewList := TStringList.Create;

getdir(0,NewPath);

if (NewPath[length(NewPath)]<>'\') then

NewPath := NewPath + '\';

ImagesHandleNeeded := ItsTheFirstPass;

DOSerr := FindFirst('*.*',faDirectory,srch);

while DOSerr=0 do

begin

if ((srch.attr and faDirectory)=faDirectory) and

((srch.name<>'.') and (srch.name<>'..')) then

begin

NewText := lowercase(srch.name);

NewText[1] := Upcase(NewText[1]);

NewList.AddObject(NewText, pointer(NewStr(NewPath+NewText)));

end;

DOSerr := FindNext(srch);

end;

sysutils.FindClose(srch);

NewList.Sorted := true;

with NewList do

for i := 0 to Count-1 do

begin

cNode := Items.AddChildObject(pNode,Strings[i], PString(Objects[i]));

with cNode do

begin

NewText := PString(Data)^;

HasChildren := ItHasChildren(NewText);

if ImagesHandleNeeded then

begin

Images.Handle := TheImage(NewText, SHGFI_SYSICONINDEX or SHGFI_SMALLICON, false);

ImagesHandleNeeded := false;

end;

ImageIndex := TheImage(NewText, SHGFI_SYSICONINDEX or SHGFI_SMALLICON, true);

SelectedIndex := TheImage(NewText, SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_OPENICON, True);

if AnsiCompareText(NewText,fCurrentPath)=0 then

begin

Expanded := true;

StateIndex := SelectedIndex;

Self.Selected := cNode;

end

else

if (pos(uppercase(NewText),tPath)=1) then

begin

Expanded := true;

tNode := cNode;

end;

end;

end;

NewList.Free;

Items.EndUpdate;

if Assigned(tNode) then

TopItem := tNode;

Screen.cursor := cCursor;

end;

실행하기

function fileExec(const aCmdLine: String; aHide, aWait: Boolean): Boolean;

var

StartupInfo : TStartupInfo;

ProcessInfo : TProcessInformation;

begin

{setup the startup information for the application }

FillChar(StartupInfo, SizeOf(TStartupInfo), 0);

with StartupInfo do

begin

cb:= SizeOf(TStartupInfo);

dwFlags:= STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;

if aHide then wShowWindow:= SW_HIDE

else wShowWindow:= SW_SHOWNORMAL;

end;

Result := CreateProcess(nil,PChar(aCmdLine), nil, nil, False,

NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);

if aWait then

if Result then

begin

WaitForInputIdle(ProcessInfo.hProcess, INFINITE);

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

end;

end;

function fileRedirectExec(const aCmdLine: String; Strings: TStrings): Boolean;

var

StartupInfo : TStartupInfo;

ProcessInfo : TProcessInformation;

aOutput : Integer;

aFile : String;

begin

Strings.Clear;

{ Create temp. file for output }

aFile:=FileTemp('.tmp');

aOutput:=FileCreate(aFile);

try

{setup the startup information for the application }

FillChar(StartupInfo, SizeOf(TStartupInfo), 0);

with StartupInfo do

begin

cb:= SizeOf(TStartupInfo);

dwFlags:= STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK or

STARTF_USESTDHANDLES;

wShowWindow:= SW_HIDE;

hStdInput:= INVALID_HANDLE_VALUE;

hStdOutput:= aOutput;

hStdError:= INVALID_HANDLE_VALUE;

end;

Result := CreateProcess(nil,PChar(aCmdLine), nil, nil, False,

NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);

if Result then

begin

WaitForInputIdle(ProcessInfo.hProcess, INFINITE);

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

end;

finally

FileClose(aOutput);

Strings.LoadFromFile(aFile);

DeleteFile(aFile);

end;

end;

외부 Application의Window크기 조절하기

SHOWWINDOW-외부 Application의 Window 크기 조절

아래 소스는 현재 active된 window의 list를 구한 후 그중 하나를 선택하여 Minimized, Maximized 하는 예제입니다.

procedure GetAllWindowsProc(WinHandle: HWND; Slist: TStrings);

var

P: array[0..256] of Char; {title bar를 저장 할 buffer}

begin

P[0] := #0;

GetWindowText(WinHandle, P, 255); {window's title bar를 알아낸다}

if (P[0] <> #0) then

if IsWindowVisible(WinHandle) then {invisible한 window는 제외}

Slist.AddObject(P, TObject(WinHandle)); {window의 handle 저장}

end;

procedure GetAllWindows(Slist: TStrings);

var

WinHandle: HWND;

Begin

WinHandle := FindWindow(nil, nil);

GetAllWindowsProc(WinHandle, Slist);

while (WinHandle <> 0) do {Top level의 window부터 순차적으로 handle을 구한다}

begin

WinHandle := GetWindow(WinHandle, GW_HWNDNEXT);

GetAllWindowsProc(WinHandle, Slist);

end;

end;

procedure TForm1.B_SearchClick(Sender: TObject);

begin

ListBox1.Items.Clear;

GetAllWindows(ListBox1.Items);

end;

procedure TForm1.B_MaximizeClick(Sender: TObject);

begin

if ListBox1.ItemIndex < 0 then

System.Exit;

{선택한 window를 maximize}

ShowWindow(HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]), SW_MAXIMIZE);

end;

procedure TForm1.B_minimizeClick(Sender: TObject);

begin

if ListBox1.ItemIndex < 0 then

System.Exit;

{선택한 window를 minimize}

ShowWindow(HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]), SW_MINIMIZE);

end;

워크그룹의 호스트네임 읽어내기

program ShowSelf;

{$apptype console}

uses Windows, Winsock, SysUtils;

function HostIPFromHostEnt( const HostEnt: PHostEnt ): String;

begin

Assert( HostEnt <> nil );

// first four bytes are the host address

Result := Format( '%d.%d.%d.%d', [Byte(HostEnt^.h_addr^[0]), Byte(HostEnt^.h_addr^[1]),

Byte(HostEnt^.h_addr^[2]), Byte(HostEnt^.h_addr^[3])] );

end;

var

r: Integer;

WSAData: TWSAData;

HostName: array[0..255] of Char;

HostEnt: PHostEnt;

begin

// initialize winsock

r := WSAStartup( MakeLong( 1, 1 ), WSAData );

if r <> 0 then

RaiseLastWin32Error;

try

Writeln( 'Initialized winsock successfully...' );

// get the host name (this is the current machine)

FillChar( HostName, sizeof(HostName), #0 );

r := gethostname( HostName, sizeof(HostName) );

if r <> 0 then

RaiseLastWin32Error;

Writeln( 'Host name is ', HostName );

// get host entry (address is contained within)

HostEnt := gethostbyname( HostName );

if not Assigned(HostEnt) then

RaiseLastWin32Error;

Writeln( 'Got host info...' );

// dump out the host ip address

Writeln( 'Host address: ', HostIPFromHostEnt( HostEnt ) );

finally

WSACleanup;

end;

end.

윈도우시작메뉴 히스트로에 문서 등록하기

윈도우즈 시작메뉴에 있는 문서 히스토리에 자기가 생성한

화일을 등록할 수 있는 함수가 있습니다.

먼저 다음과 같은 프로시져를 프로그램에 넣어 주세요.

use ShellAPI, ShlObj;

procedure AddToStartDocument(FilePath: string)

begin

SHAddToRecentDocs(SHARD_PATH, PChar(FilePath));

end;

자 이제 이 함수를 사용해 봅시다. 우린 파라미터로 문서의

경로를 넘겨주면 됩니다.

예)

AddToStartDocument(C:\Test.txt);

=>책에 이렇게 나와 있는데, 미스 프린팅 같군요.

-> 요렇게 해 주세요. AddToStartDocument('C:\Test.txt');

윈도우 배경그림바꾸기

Window 배경그림 바꾸기

procedure ChangeIt;

var

Reg: TRegIniFile;

begin

Reg := TRegIniFile.Create('Control Panel');

Reg.WriteString('desktop','Wallpaper','c:\windows\kim.bmp');

Reg.WriteString('desktop', 'TileWallpaper', '1');

Reg.Free;

SystemParametersInfo(SPI_SETDESKWALLPAPER,0,nil,SPIF_SENDWININICHANGE);

end;

Status에 색깔 넣기

Status bar에 색깔 넣기

StatusBar Font의 색을 바꾸는 방법은 직접 그려주는 수 밖에 없습니다. 익히 아시겠지만 StatusBar의 Item이라 할 수 있는 TStatusPanel에는 Style이란게 있습니다. 이 값은 psText나 psOwnerDraw란 값을 갖는데 psOwnerDraw일때에는 해당 Panel을 그릴 때마다 OnDrawPanel event가 호출됩니다. 이때에 원하는 색으로 직접 그려주시면 됩니다. psOwnerDraw일때는 그려주지 않게되면 Text값을 갖고 있다 하더라도 전혀 나오질 않으므로, 반드시 위에 말한 event에서 그려주셔야 합니다.

다음에 예제를 보여드립니다.

procedure TfmMain.m_statusBarDrawPanel(StatusBar:

TStatusBar; Panel: TStatusPanel; const Rect: TRect);

begin

with StatusBar.Canvas do begin

case Panel.ID of

0 : Font.Color := clBlue;

2 : if Panel.Text = '한글' then Font.Color := clRed

else Font.Color := clBlue;

end;

FillRect(Rect);

TextOut(Rect.Left+2,Rect.Top+2,Panel.Text);

end;

end;

위에 ID란 property를 사용했는데요, 이것은 index와는 약간 차이가 있습니다. index propery와 같이 부여되긴 하지만, item이 추가, 삭제, 삽입되더라도 ID의 값은 변하질 않습니다.

다시말해 한번 부여된 ID는 다시 사용되지 않습니다.

TreeView 프린트하기

TreeView and Print

paintTo can be made to work, you just have to scale the printer.canvas in the ratio of screen to printer resolution.

procedure TForm1.Button2Click(Sender: TObject);

begin

Printer.BeginDoc;

try

printer.canvas.moveto(100,100);

SetMapMode( printer.canvas.handle, MM_ANISOTROPIC );

SetWindowExtEx(printer.canvas.handle,

GetDeviceCaps(canvas.handle, LOGPIXELSX),

GetDeviceCaps(canvas.handle, LOGPIXELSY),

Nil);

SetViewportExtEx(printer.canvas.handle,

GetDeviceCaps(printer.canvas.handle, LOGPIXELSX),

GetDeviceCaps(printer.canvas.handle, LOGPIXELSY),

Nil);

treeview1.PaintTo( printer.canvas.handle, 100, 100 );

finally

printer.enddoc;

end;

end;