深入核心VCL架构剖析-笔记1

1、经过这么多年发展的VCL到底是什么?

2、我们为什么需要VCL?

3、VCL和Windows程序设计有什么关系?

4、delphi不使用VCL可以写Windows应用程序吗?

5、VCL与其他的WINdows Framework有何不同?

6、windows上到底有多少Framework?他们之间有何不同?

                                                                 第一章:回到从前

消息驱动模型:因为我们不知道每一个应用程序在何时回发生/出发事件,以及会触发什么事件,更不知道何时会点击鼠标、键盘,因此我们无法设计一个大型循环,然后在此循环中不断检查每一个应用程序是否触发了特定的事件。即便能够设计出来,我们可以想象,这仍然是非常愚蠢的做法,因为这样会让系统不时的处于百分百的运作当中。因此,反过来想:既然系统适应不了事件,何不让事件来适应系统,让事件来驱动系统。

由于执行环境必须转换事件为消息,因此我们可以说消息既是事件。因此我们要为消息(事件)定义一个结构,我们暂时取名:MyMessage。当然,需要一个ID来表示发生的特定事件。

MyMessage = packed record
   MessageID:  LongInt;
end;

当然,一个消息不可能只有一个ID,还必须有一些其他的成员。

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

这样,基本一个消息就算完善了。这里顺便说一下packed  record  与 record之间的区别:Record的数据各个字节都是对齐的,数据格式比较完整,所以这种格式相对packed占用的内存比较大, 但是因为格式比较整齐,所以电脑读取这个类型的数据的时候速度比较快。 而Packed Record对数据进行了压缩,节省了内存空间,当然他的速度也变的慢了。

此时,对于多窗口的应用程序,消息是如何分派的呢,对了,就是消息中的hwnd字段。在此之前,消息会进入消息队列中,然后系统根据hwnd字段分派消息到各个窗口中。

现在消息有了,但消息一般是通过窗口触发事件响应的,接下来我们看看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;
  s: TFNWndProc;
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_UseDefault,cw_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.

 

 

 

转载于:https://www.cnblogs.com/lipengpeng/archive/2013/03/29/2989221.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值