API窗口问题(100分)

  • 主题发起人 主题发起人 jingtao
  • 开始时间 开始时间
J

jingtao

Unregistered / Unconfirmed
GUEST, unregistred user!
//file:Project1.dpr<br>program Project1;<br><br>uses<br>&nbsp; Windows,<br>&nbsp; Unit_MainForm;<br><br>{$R *.res}<br><br>Var<br>TheMessage:TMsg;<br><br>begin<br>&nbsp; if not MyCreateWinForm('strServerClassName','strServrerCaption') then halt;<br>&nbsp; while GetMessage(TheMessage,0,0,0) do<br>&nbsp; begin<br>&nbsp; &nbsp; TranslateMessage(TheMessage);<br>&nbsp; &nbsp; DispatchMessage(TheMessage);<br>&nbsp; &nbsp; // sleep(20);<br>&nbsp; end;<br>end.<br><br>//file:<br>unit Unit_MainForm;<br><br>interface<br>uses<br>&nbsp; Windows;<br><br>function MyCreateWinForm(strWindowClass,strWindowCaption:string):Bool;stdcall;<br>implementation<br><br>const<br>&nbsp;WM_CREATE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $0001;<br>&nbsp;WM_DESTROY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $0002;<br>&nbsp;Timer1:integer=1;<br><br>procedure OnFormCreate;forward;<br>procedure OnFormDestroy;forward;<br>procedure OnTimer1;forward;<br>var<br>WinClass: TWndClassA; <br>hWindow: HWND; &nbsp; &nbsp; &nbsp; <br><br>procedure Time1pro(hWnd: Longint; uMsg: UINT; idEvent: UINT; Time: DWORD); stdcall;<br>begin<br>OnTimer1;<br>end;<br>function WindowProc(hWindow: HWnd; Message, wParam, lParam: Integer): Integer; stdcall;<br>begin<br>Result:=0;<br>case Message of<br>&nbsp; &nbsp;WM_Create:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; OnFormCreate;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp;WM_DESTROY:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; OnFormDestroy;<br>&nbsp; &nbsp; &nbsp; &nbsp; PostQuitMessage(0);<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; else<br>&nbsp; &nbsp; Result := DefWindowProc(hWindow, Message, wParam, lParam);<br>&nbsp; end;<br>end;<br>function MyCreateWinForm(strWindowClass,strWindowCaption:string):Bool;stdcall;<br>var<br>hFont: Integer;<br>Inst: HINST;<br>begin<br>{ Register Custom WndClass }<br>&nbsp; Result:=False;<br>&nbsp; Inst := hInstance;<br>&nbsp; with WinClass do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; style := CS_CLASSDC or CS_PARENTDC;<br>&nbsp; &nbsp; &nbsp; lpfnWndProc := @WindowProc;<br>&nbsp; &nbsp; &nbsp; hInstance := Inst;<br>&nbsp; &nbsp; &nbsp; hbrBackground := color_btnface + 1;<br>&nbsp; &nbsp; &nbsp; lpszClassname := Pchar(strWindowClass);<br>&nbsp; &nbsp; &nbsp; hIcon := LoadIcon(Inst, 'Mainicon');<br>&nbsp; &nbsp; &nbsp; hCursor := LoadCursor(0, IDC_ARROW);<br>&nbsp; &nbsp; end; { with }<br>&nbsp; &nbsp; if &nbsp;RegisterClass(WinClass)=0 then Exit;<br>&nbsp; &nbsp; hWindow := CreateWindowEx(WS_EX_WINDOWEDGE, Pchar(strWindowClass),Pchar(strWindowCaption),<br>&nbsp; &nbsp; WS_MINIMIZEBOX or WS_SYSMENU or WS_VISIBLE,<br>&nbsp; &nbsp; (GetSystemMetrics(SM_CXSCREEN) - 300) div 2,<br>&nbsp; &nbsp; (GetSystemMetrics(SM_CYSCREEN) - 300) div 2, 300, 330, 0, 0, Inst, nil);<br>&nbsp; &nbsp; if hWindow=0 then Exit;<br><br>&nbsp; SetTimer(hWindow, Timer1, 4000, @Time1pro);{注意这里!!!}<br>&nbsp; UpdateWindow(hWindow);<br>&nbsp; Result:=True;<br>end;<br><br><br>{==============================================================================}<br>procedure OnFormCreate;<br>begin<br>MessageBox(0,'OnFormCreate','',MB_OK);<br>end;<br>procedure OnFormDestroy;<br>begin<br>MessageBox(0,'OnFormDestroy','',MB_OK);<br>end;<br>procedure OnTimer1;<br>begin<br>KillTimer(hWindow,Timer1);<br>MessageBox(0,'OnTimer1','',MB_OK);<br>end;<br>{==============================================================================}<br>end.<br><br><br>如果把SetTimer(hWindow, Timer1, 4000, @Time1pro);{注意这里!!!}<br>这句放在<br>procedure OnFormCreate;<br>begin<br>MessageBox(0,'OnFormCreate','',MB_OK);<br>end;<br>里面,发现OnTimer1;里面的KillTimer(hWindow,Timer1);根本不起作用.为什么???放在<br>WM_Create:却是可以的.
 
这个你看一下吧<br>program AutoShutDown;<br><br>uses<br>&nbsp; ExceptionLog,<br>&nbsp; Windows,<br>&nbsp; ShellAPI,<br>&nbsp; Sysutils,<br>&nbsp; Messages;<br><br>{$R *.RES}<br>var<br>&nbsp; WinClass: TWndClassA;<br>&nbsp; Handle: hwnd;<br>&nbsp; Inst, Button1, Label1, Edit1: Integer;<br>&nbsp; Msg: TMsg;<br>&nbsp; tid: TNotifyIconDataA;<br>&nbsp; sdt: tdatetime;<br>&nbsp; timerid: integer;<br>&nbsp; hFont: Integer;<br>const<br>&nbsp; AppName = 'AutoShutDown';<br>&nbsp; st = '定时关机';<br>&nbsp; About = st + ' 1.0, Keyes.chen@263.net, Keyes 1999.10.23';<br>&nbsp; gjs = '设定关机时间';<br><br>procedure SetShutdownTime;<br>var<br>&nbsp; Textlength: Integer;<br>&nbsp; Text: PChar; i: tdatetime;<br>begin<br>&nbsp; TextLength := GetWindowTextLength(Edit1);<br>&nbsp; GetMem(Text, TextLength + 1);<br>&nbsp; GetWindowText(Edit1, Text, TextLength + 1);<br>&nbsp; try<br>&nbsp; &nbsp; i := Strtodatetime(Text);<br>&nbsp; &nbsp; if i &lt;= now then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; MessageBox(handle, '不对吧!太早了.', '错误', mb_ok or MB_ICONERROR);<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; sdt := i;<br>&nbsp; &nbsp; timerid := Settimer(handle, 1000, 1000, nil);<br>&nbsp; &nbsp; Showwindow(handle, sw_hide);<br>&nbsp; &nbsp; lstrcpy(tid.szTip, pchar(st + ' &nbsp;关机时间:' + Datetimetostr(sdt)));<br>&nbsp; &nbsp; Shell_NotifyIcon(nim_modify, @tid);<br>&nbsp; except<br>&nbsp; &nbsp; Killtimer(handle, timerid);<br>&nbsp; &nbsp; Messagebox(handle, pchar('关机时间设定错误'#13#10#13#10 + '格式因该是:' + Datetimetostr(now)), AppName, Mb_ok or MB_ICONINFORMATION);<br>&nbsp; end;<br>&nbsp; FreeMem(Text, TextLength + 1);<br>end;<br><br>function WindowProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;<br>var pt: tpoint; pm: Hmenu;<br>begin<br>&nbsp; result := 0;<br>&nbsp; case uMsg of<br>&nbsp; &nbsp; wm_timer:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if now &gt;= sdt then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Killtimer(handle, timerid);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExitWindowsEx(EWX_SHUTDOWN or EWX_Force, 0);<br>// &nbsp; &nbsp;PostMessage(handle,wm_Destroy,0,0);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; wm_User:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; case lparam of<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WM_LBUTTONDBLCLK:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showwindow(handle, sw_restore);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setforegroundwindow(handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wm_LButtonDown, wm_RButtonDown:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pm := CreatePopupMenu;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppendMenu(pm, 0, Ord('S'), gjs);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppendMenu(pm, 0, Ord('A'), '关于...');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppendMenu(pm, mf_Separator, 0, nil);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AppendMenu(pm, 0, Ord('E'), '退出');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if TrackPopupMenu(pm, tpm_BottomAlign or tpm_RightAlign, pt.x, {GetDeviceCaps(dc,Vertres)} pt.y, 0, handle, nil) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DestroyMenu(pm)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; wm_Destroy:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shell_NotifyIcon(nim_Delete, @tid);<br>&nbsp; &nbsp; &nbsp; &nbsp; Killtimer(handle, timerid);<br>&nbsp; &nbsp; &nbsp; &nbsp; halt;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; wm_Command:<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if (lParam = Button1) then begin SetshutdownTime; exit end;<br>&nbsp; &nbsp; &nbsp; &nbsp; case Loword(wParam) of<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Ord('A'): MessageBox(0, About, AppName, mb_ok or MB_ICONINFORMATION);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Ord('E'): PostMessage(handle, wm_Close, 0, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Ord('S'):<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Showwindow(handle, sw_restore);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; Result := DefWindowProc(hWnd, uMsg, wParam, lParam);<br>end;<br><br>begin<br>&nbsp; { ** Register Custom WndClass ** }<br>&nbsp; if FindWindow(AppName, nil) &lt;&gt; 0 then begin<br>&nbsp; &nbsp; Messagebox(handle, '已经有一个AutoShutDown运行了', AppName, mb_ok or MB_ICONWARNING);<br>&nbsp; &nbsp; halt(0);<br>&nbsp; end;<br>&nbsp; Inst := hInstance;<br>&nbsp; with WinClass do<br>&nbsp; begin<br>&nbsp; &nbsp; style := CS_CLASSDC or CS_PARENTDC;<br>&nbsp; &nbsp; lpfnWndProc := @WindowProc;<br>&nbsp; &nbsp; hInstance := Inst;<br>&nbsp; &nbsp; hbrBackground := color_btnface + 1;<br>&nbsp; &nbsp; lpszClassname := AppName;<br>&nbsp; &nbsp; hCursor := LoadCursor(0, IDC_ARROW);<br>&nbsp; end;<br>&nbsp; RegisterClass(WinClass);<br>&nbsp; Handle := CreateWindowEx(WS_EX_WINDOWEDGE, AppName, 'AutoShutDown 1.00',<br>&nbsp; &nbsp; WS_VISIBLE {or WS_SIZEBOX} or WS_CAPTION or WS_SYSMENU,<br>&nbsp; &nbsp; 283, 238, 325, 65, 0, 0, Inst, nil);<br>&nbsp; Button1 := CreateWindow('Button', 'OK', WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,<br>&nbsp; &nbsp; 236, 8, 75, 20, handle, 0, Inst, nil);<br>&nbsp; Label1 := Createwindow('Static', '', WS_VISIBLE or WS_CHILD or SS_LEFT,<br>&nbsp; &nbsp; 8, 12, 80, 13, Handle, 0, Inst, nil);<br>&nbsp; Edit1 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', Pchar(Datetimetostr(now)), WS_CHILD or WS_VISIBLE or<br>&nbsp; &nbsp; WS_BORDER {or ES_PASSWORD}, 88, 8, 141, 21, Handle, 0, Inst, nil);<br>&nbsp; hFont := CreateFont(-12, 0, 0, 0, 500, 0, 0, 0, GB2312_CHARSET,<br>&nbsp; &nbsp; OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,<br>&nbsp; &nbsp; DEFAULT_PITCH or FF_DONTCARE, '宋体');<br>&nbsp; if hFont &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; SendMessage(Button1, WM_SETFONT, hFont, 0);<br>&nbsp; &nbsp; SendMessage(Label1, WM_SETFONT, hFont, 0);<br>&nbsp; &nbsp; SendMessage(Edit1, WM_SETFONT, hFont, 0);<br>&nbsp; end;<br>&nbsp; SetWindowText(Label1, pchar(gjs + ':'));<br>&nbsp; SetFocus(Edit1);<br>&nbsp; UpdateWindow(Handle);<br>&nbsp; tid.cbSize := sizeof(tid);<br>&nbsp; tid.Wnd := handle;<br>&nbsp; tid.uID := 1;<br>&nbsp; tid.uFlags := nif_Message or nif_Icon or nif_Tip;<br>&nbsp; tid.uCallBackMessage := wm_User;<br>&nbsp; tid.hIcon := LoadIcon(hInstance, 'MAINICON');<br>&nbsp; lstrcpy(tid.szTip, st);<br>&nbsp; Shell_NotifyIcon(nim_Add, @tid);<br>&nbsp; while (GetMessage(Msg, Handle, 0, 0)) do<br>&nbsp; begin<br>&nbsp; &nbsp; TranslateMessage(msg);<br>&nbsp; &nbsp; DispatchMessage(msg);<br>&nbsp; end;<br>end.<br>
 
好东西,收藏。
 
在OnFormCreate时的hWindow是个全局变量,而在WindowProc中的hWindow是个局部变量<br>
 
原因很简单:WM_CREATE消息是在CreateWindowEx时触发的<br><br>程序的逻辑是这样的:<br>1、主程序调用MyCreateWinForm中的:<br>&nbsp; &nbsp;hWindow := CreateWindowEx(...);//这时候hWindow=0<br>2、在CreateWindowEx函数还未返回的时候在函数WindowProc(hWindow: HWnd;...)里面触发了WM_CREATE消息,在WindowProc里面的hWindow是局部变量,是真正创建的窗口Handle(假设为123)<br>3、如果在WM_CREATE的时候调用SetTimer(hWindow...),也就是这样的:SetTimer(123, ...)<br>4、如果OnFormCreate里面调用SetTimer(hWindow...),这时的hWindow是你定义的全局变量,并且这时候hWindow=0,调用过程也就成了SetTimer(0, ...)<br><br>5、当在OnTimer1中KillTimer(hWindow,Timer1);时CreateWindowEx早已返回了,全局变量hWindow也变成了真正窗口的Handle(123),所以如果是在WM_CREATE中调用的SetTimer(123, ...),这时就可以真正的KillTimer了,如果是在OnFormCreate中做的,KillTimer在hWindow(123)中根本找不到这个Timer,所以也就不起作用了(这时候就要KillTimer(0, ...)才可以~~~~~~)(KillTimer的第一个参数要求的是与SetTimer中相同的参数)<br>
 
多人接受答案了。
 
后退
顶部