说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

写小执行程序-Delphi资料

HTML文档下载 WORD文档下载 PDF文档下载
写小执行程序-Delphi资料

首先看看程序头的写法:

program DeskPop;

uses Windows

Messages

ShellAPI

sysutils;

{$R *.RES}

{可以看出本程序比普通的 Delphi 程序用到的 Unit 少的多。 下面声明了全局常量和变量,暂时可以不管他们。}

const AppName = 'DeskTop Hide';

var

x: integer;

tid: TNotifyIconData;

WndClass: array[0..50] of char;

{现在进入程序的主要部分,首先是定义了一批过程,为了能让读者更好地理解,我们先把这些过程跳过去,先说主程序。主程序位于程序的最后,这样做的好处是可以直接使用程序中定义的过程。主程序十分简单:}

begin

WinMain;

end.

{看来所有的工作都由 WinMain 完成了。这个 WinMain 使用标准的 WinAPI 函数进行编程,主要步骤是:先声明一个窗口类,然后创建一个主窗口,最后进入消息循环,直到程序结束。}

procedure WinMain;

var

Wnd: hWnd; {声明窗口句柄(Handle)变量}

Msg: TMsg; {声明消息变量}

cls: TWndClass; {窗口类变量}

begin {Previous instance running ? If so

exit }

{检查是否程序已经运行,如果已经运行则调用 Panic 过程退出}

if FindWindow (AppName

Nil) <> 0 then Panic (AppName + ' is already running.');

{Register the window class}

{这里的注册窗口类程序是例行公事,照抄即可}

FillChar (cls

sizeof (cls)

0); {用这一句将窗口类变量 cls 清零}

cls.lpfnWndProc := @DummyWindowProc; {取回调函数DummyWindowProc的地址}

cls.hInstance := hInstance; {实例句柄}

cls.lpszClassName := AppName; {窗口类名}

RegisterClass (cls); {注册窗口类cls}

{现在可以创建程序的主窗口了-在本程序中是个虚拟窗口}

{Now create the dummy window}

Wnd := CreateWindow (AppName

AppName

ws_OverlappedWindow

cw_UseDefault

cw_UseDefault

cw_UseDefault

cw_UseDefault

0

0

hInstance

Nil);

x:= 0; {变量X其实是个开关变量,记录现在是否已经隐藏了桌面}

{如果窗口创建成功,则显示窗口,并进入消息循环}

if Wnd <> 0 then

begin

ShowWindow (Wnd

sw_Hide);{本例中窗口是隐藏的}

{下面进入消息循环,该循环将不断运行直到 GetMessage 返回0}

while GetMessage (Msg

0

0

0) do

begin

TranslateMessage (Msg);

DispatchMessage (Msg);

end;

end;

end;

{现在看来,程序的主框架很明了,但是它还不能完成任何任务。过程 Panic 将显示一个对话框后退出程序,它在 Winmain 过程的开始部分被调用,其实 Panic 的功能很简单,之所以要写成一个函数的原因恐怕一方面是结构化编程的需要,另一方面借此避开了 String 和 PChar 的转换。}

procedure Panic (szMessage: PChar);

begin

if szMessage <> Nil then MessageBox (0

szMessage

AppName

mb_ok);

Halt (0);

end;

{下面是回调 (Callback) 函数 DummyWindowProc,如果说 Winmain 过程是本程序-或者说是本应用或实例的生命,那么这个回调函数可以说是主窗口的灵魂。每一个标准的或者说是规范的 Windows 窗口都有一个回调函数,以处理发给该窗口的消息。所谓“回调”的意思是这个函数不是由程序直接调用的,而是由 Windows 系统调用(还记得我们在窗口类中给 lpfnWndProc 赋过值吗, 这就是事件驱动编程。}

function DummyWindowProc (Wnd: hWnd; Msg

wParam: Word; lParam: LongInt) :LongInt; stdcall;

{注意这里有一个 stdcall; 定义了回调函数}

var

TrayHandle: THandle;

dc: hDC;

i: Integer;

pm: HMenu;

pt: TPoint;

begin

DummyWindowProc := 0;

{下面两句是找到 Win95 任务栏的句柄}

StrPCopy(@WndClass[0]

'Progman');

TrayHandle := FindWindow(@WndClass[0]

nil);

{下面开始处理消息}

case Msg of {收到窗口创建消息 - 在任务栏上显示一个图标}

wm_Create:begin

tid.cbSize := sizeof (tid);

tid.Wnd := Wnd;

tid.uID := 1;

tid.uFlags := nif_Message or nif_Icon or nif_Tip;

tid.uCallBackMessage := wm_User;

tid.hIcon := LoadIcon (hInstance

'MAINICON');

lstrcpy (tid.szTip

'Desktop is on');

Shell_NotifyIcon (nim_Add

@tid);

end;

wm_Destroy: {收到关闭窗口消息时的处理}

begin

Shell_NotifyIcon (nim_Delete

@tid);

PostQuitMessage (0);

ShowWindow(TrayHandle

SW_RESTORE);

end;

wm_Command: {收到菜单消息时调用 HandleCommand 过程,并退出函数}

begin

HandleCommand (Wnd

LoWord (wParam));

Exit;

end;

wm_User: {收到其他用户消息时的处理}

{如果单击了鼠标左键, 则打开或关闭桌面}

if (lParam = wm_LButtonDown) then

begin

if x = 0 then

begin

ShowWindow(TrayHandle

SW_HIDE);

tid.hIcon := LoadIcon (hInstance

'offICON');

lstrcpy (tid.szTip

'Desktop is off');

Shell_NotifyIcon (NIM_MODIFY

@tid);

x:=1

end

else

begin

ShowWindow(TrayHandle

SW_RESTORE);

tid.hIcon := LoadIcon (hInstance

'ONICON');

lstrcpy (tid.szTip

'Desktop is on');

Shell_NotifyIcon (NIM_MODIFY

@tid);

x:= 0;

end;

end {end of if}

else

{如果是鼠标右键,则动态生成一个弹出式菜单}

if (lParam = wm_RButtonDown) then

begin

GetCursorPos (pt);

pm := CreatePopupMenu;

AppendMenu (pm

0

Ord ('A')

'About DeskTop Hide...');

AppendMenu (pm

mf_Separator

0

Nil);

AppendMenu (pm

0

Ord ('E')

'Exit DeskTop Hide');

SetForegroundWindow (Wnd);

dc := GetDC (0);

if TrackPopupMenu (pm

tpm_BottomAlign or tpm_RightAlign

pt.x

GetDeviceCaps(dc

HORZRES){pt.y}

0

Wnd

Nil) then

SetForegroundWindow (Wnd);

DestroyMenu (pm)

end; {end of if}

end; {end of case}

{在处理过消息之后,还要调用默认函数,以完成标准的Windows程序应该执行的任务,所以这一句非常重要}

DummyWindowProc := DefWindowProc (Wnd

Msg

wParam

lParam);

end;

{这个就是处理菜单消息的过程}

procedure HandleCommand (Wnd: hWnd; Cmd: Word);

begin

case Cmd of

Ord ('A'): MessageBox (0

'Freeware brian.slack@strath.ac.uk 1997'

AppName

mb_ok);

Ord ('E'): PostMessage (Wnd

wm_Close

0

0);

end;

end;

至此我们已经完成了这个只有38K的能将 Win95 桌面隐藏起来的程序,只要将本文中所有的函数和过程的顺序倒置,并将主程序放到最后,即可编译通过。

备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘