procedure TApplication.Run; begin FRunning :=True; try AddExitProc(DoneApplication); if FMainForm <> nil then begin case CmdShow of SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized; SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized; end; if FShowMainForm then if FMainForm.FWindowState = wsMinimized then Minimize else FMainForm.Visible :=True; repeat try HandleMessage; except HandleException(Self); end; until Terminated; end; finally FRunning :=False; end; end;
procedure TApplication.HandleMessage; var Msg: TMsg; begin ifnot ProcessMessage(Msg) then Idle(Msg); end; function TApplication.ProcessMessage(var Msg: TMsg): Boolean; var Handled: Boolean; begin Result :=False; // 取消息 if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin Result :=True; if Msg.Message <> WM_QUIT then begin Handled :=False; if Assigned(FOnMessage) then FOnMessage(Msg, Handled); ifnot IsHintMsg(Msg) andnot Handled andnot IsMDIMsg(Msg) and not IsKeyMsg(Msg) andnot IsDlgMsg(Msg) then begin // 熟悉的分发消息过程 TranslateMessage(Msg); DispatchMessage(Msg); end; end else // 如果取到的消息为WM_QUIT,则将Fterminate设为真 // 以通知主消息循环退出 // 这和WindowDemo程序中判断GetMessage()函数返回值是否为0等效 // 因为GetMessage()函数取出的消息如果是WM_QUIT,它的返回值为0 FTerminate :=True; end; end;
procedure TApplication.WndProc(var Message: TMessage); type // 函数内嵌定义的类型,只限函数内部使用 TInitTestLibrary =function(Size: DWord; PAutoClassInfo: Pointer): Boolean; stdcall; var I: Integer; SaveFocus, TopWindow: HWnd; InitTestLibrary: TInitTestLibrary; // 内嵌函数,默认的消息处理 // 调用Windows的API函数DefWindowProc procedure Default; begin with Message do Result := DefWindowProc(FHandle, Msg, WParam, LParam); end; procedure DrawAppIcon; var DC: HDC; PS: TPaintStruct; begin with Message do begin DC := BeginPaint(FHandle, PS); DrawIcon(DC, 0, 0, GetIconHandle); EndPaint(FHandle, PS); end; end; begin try Message.Result :=0; for I :=0to FWindowHooks.Count -1do if TWindowHook(FWindowHooks[I]^)(Message) thenExit; CheckIniChange(Message); with Message do // 开始庞大的case分支,对不同的消息做出不同的处理 case Msg of WM_SYSCOMMAND: case WParam and $FFF0 of SC_MINIMIZE: Minimize; SC_RESTORE: Restore; else Default; end; WM_CLOSE: if MainForm <> nil then MainForm.Close; WM_PAINT: if IsIconic(FHandle) then DrawAppIcon else Default; WM_ERASEBKGND: begin Message.Msg := WM_ICONERASEBKGND; Default; end; WM_QUERYDRAGICON: Result := GetIconHandle; WM_SETFOCUS: begin PostMessage(FHandle, CM_ENTER, 0, 0); Default; end; WM_ACTIVATEAPP: begin Default; FActive := TWMActivateApp(Message).Active; if TWMActivateApp(Message).Active then begin RestoreTopMosts; PostMessage(FHandle, CM_ACTIVATE, 0, 0) end else begin NormalizeTopMosts; PostMessage(FHandle, CM_DEACTIVATE, 0, 0); end; end; WM_ENABLE: if TWMEnable(Message).Enabled then begin RestoreTopMosts; if FWindowList <> nil then begin EnableTaskWindows(FWindowList); FWindowList := nil; end; Default; endelse begin Default; if FWindowList = nil then FWindowList := DisableTaskWindows(Handle); NormalizeAllTopMosts; end; WM_CTLCOLORMSGBOX..WM_CTLCOLORSTATIC: Result := SendMessage(LParam, CN_BASE + Msg, WParam, LParam); WM_ENDSESSION: if TWMEndSession(Message).EndSession then FTerminate :=True; WM_COPYDATA: if (PCopyDataStruct(Message.lParam)^.dwData = DWORD($DE534454)) and (FAllowTesting) then if FTestLib =0then begin FTestLib := SafeLoadLibrary('vcltest3.dll'); if FTestLib <>0then begin Result :=0; @InitTestLibrary := GetProcAddress(FTestLib, 'RegisterAutomation'); if @InitTestLibrary <> nil then InitTestLibrary(PCopyDataStruct(Message.lParam)^.cbData, PCopyDataStruct(Message.lParam)^.lpData); end else begin Result := GetLastError; FTestLib :=0; end; end else Result :=0; CM_ACTIONEXECUTE, CM_ACTIONUPDATE: Message.Result := Ord(DispatchAction(Message.Msg, TBasicAction(Message.LParam))); CM_APPKEYDOWN: if IsShortCut(TWMKey(Message)) then Result :=1; CM_APPSYSCOMMAND: if MainForm <> nil then with MainForm do if (Handle <>0) and IsWindowEnabled(Handle) and IsWindowVisible(Handle) then begin FocusMessages :=False; SaveFocus := GetFocus; Windows.SetFocus(Handle); Perform(WM_SYSCOMMAND, WParam, LParam); Windows.SetFocus(SaveFocus); FocusMessages :=True; Result :=1; end; CM_ACTIVATE: if Assigned(FOnActivate) then FOnActivate(Self); CM_DEACTIVATE: if Assigned(FOnDeactivate) then FOnDeactivate(Self); CM_ENTER: ifnot IsIconic(FHandle) and (GetFocus = FHandle) then begin TopWindow := FindTopMostWindow(0); if TopWindow <>0then Windows.SetFocus(TopWindow); end; WM_HELP, // MessageBox( MB_HELP) CM_INVOKEHELP: InvokeHelp(WParam, LParam); CM_WINDOWHOOK: if wParam =0then HookMainWindow(TWindowHook(Pointer(LParam)^)) else UnhookMainWindow(TWindowHook(Pointer(LParam)^)); CM_DIALOGHANDLE: if wParam =1then Result := FDialogHandle else FDialogHandle := lParam; WM_SETTINGCHANGE: begin Mouse.SettingChanged(wParam); SettingChange(TWMSettingChange(Message)); Default; end; WM_FONTCHANGE: begin Screen.ResetFonts; Default; end; WM_NULL: CheckSynchronize; else Default; end; except HandleException(Self); end; end;