delphi VCL核心感想 1

来源:互联网 发布:谷笑爷 知乎 编辑:程序博客网 时间:2024/06/03 07:27

消息结构:

MyMessage = packed record
  hwnd: HWND;     //应用程序窗口识别值
  MessageID: Longint;
  wParam: Longint;
  lParam: Longint;
  time: Longint;
  pt: TPoint;
end;


//窗口定义
MyWindowClassInfo = packed record
  style : UINT;    //窗口类型
  iWidth: Intger;  //窗口高度
  iHeight: Integer; //宽度
  lpfnwndProc: Pointer;  //代表应用程序可以把任何的函数地址指定给此字段以代表可以处理此窗口消息 的函数
  hIcon: HICON;   
  hCursor: HCURSOR;  //窗口使用的光标种类
  hbrBackground: HBRUSH;
  lpszMenuName: PAnsichar;
  lpszClassName: PAnsichar; //窗口的类名称
  hIconSm : HICON;

这三个问题如果可以回答的完美,那么delphi(以及windows)的消息处理流程就基本到家了。

1、 应用程序可能拥有许多窗口,如何把触发的消息分发给正确的窗口去处理?  

答:在消息结构中添加窗口ID。

2、把消息分派给应用程序或是窗口是如何办到的?

答:在执行环境将事件转换为消息记录后,应用程序会将此记录提供给窗口的回调函数(即上面窗口结构中的lpfnwndProc),我们可以看到lpfnwndProc为指针类型,此即为处理消息的函数的地址。

3、当分派了消息给窗口之后,窗口要如何处理次消息?
答:第二个问题只是说明了应用程序会将此记录提供给窗口的回调函数,但回调函数由谁调用呢,对了,有执行环境调用。这样此消息就算顺利的被执行了。


getMessage  translateMessage  dispatchmessage此三个函数为消息处理函数。


撰写windows应用程序包含了四个简单的步骤:
1、定义窗口类的内容,以决定窗口的创建格式以及回调函数;
2、注册窗口类;
3、创建窗口;

4、进入窗口消息处理循环以便让回调函数处理窗口消息,直到应用程序结束为止;

例子:

program Project1;


uses
  Forms,windows,Messages,sysUtils,
  Unit1 in 'Unit1.pas' {Form1};
const
  AppName = 'ddd';


{$R *.res}
function WindowProc(window: HWND;
                    AMessage: UINT;
                    WParam: WPARAM;
                    LParam: LPARAM):LRESULT;  stdcall;export;
var
  dc: HDC;
  ps: TPaintStruct;
  r : TRect;
begin
  WindowProc := 0;
  case AMessage of
    WM_PAINT:
      begin
        dc := BeginPaint(window,ps);
        GetClientRect(window,r) ;
        DrawText(dc,'使用pascal撰写的Native Windows 程序',1,r,DT_SINGLELINE or DT_CENTER or DT_VCENTER);
        EndPaint(window,ps);
        Exit;
      end;
    WM_DESTROY:
      begin
        PostQuitMessage(0);
        Exit;
      end;    
  end;
  WindowProc := DefWindowProc(window,AMessage,WParam,LParam);
end;


{ Register the window class}
function WinRegister: Boolean;
var
  WindowClass: WNDCLASS;
begin
  WindowClass.style := CS_VREDRAW or CS_HREDRAW;
  WindowClass.lpfnWndProc := TFNWndProc(@WindowProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := SYSTEM.MainInstance;
  WindowClass.hCursor := LoadCursor(0,IDC_ARROW) ;
  WindowClass.hIcon := LoadIcon(0,IDI_APPLICATION) ;
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := AppName;
  Result := RegisterClass(WindowClass) <> 0 ;
end;


{ create the window class}
function WinCreate: HWND;
    var
      hWindow: HWND;
    begin
      hWindow := CreateWindow(AppName,'dddddddddd',WS_OVERLAPPEDWINDOW,cw_UseDefault,
                                  cw_UseDefault,cw_UseDefaultcw_UseDefault,0,0,system.MainInstance,nil);
      if hWindow <> 0 then
        begin
          ShowWindow(hWindow,CmdShow);
          ShowWindow(hWindow,SW_SHOW);
          UpdateWindow(hWindow);
        end;
      Result := hWindow;
    end;
var
  AMessage: TMsg;
  hWindow: HWND;
begin  //  主程序入口
  if not WinRegister then
    begin
      MessageBox(hWindow,'',nil,MB_OK);
      Exit;
    end;
    hWindow := WinCreate;
    if LongInt(hWindow) = 0  then
      begin
        MessageBox(hWindow,'',nil,MB_OK);
        Exit;
      end;
    while GetMessage(AMessage,0,0,0) do
      begin
        TranslateMessage(AMessage);
        DispatchMessage(AMessage);
      end;
    Halt(AMessage.wParam);  
end;    
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.






原创粉丝点击