接触Delphi也已经有好长时间了,使用Delphi进行程序开发非常方便、快速,Delphi本身就提供了大量的组件(网上还有更多的组件)进行程序开发,这大大减轻了程序员的工作量,但是越方便越说明Delphi本身在背后为我们做的工作就越多,也许很多人没有考虑过这些,还在充分的享受着它带给我们的快捷与方便。我也是个C的爱好者,学习和使用C也有好长一段时间了,学了C/C++以后,要进行Windows程序设计,常规的有两种方法一种是利用SDK开发包,还有就是MFC,现在还有BCB,等等更多,当时很多人都把SDK作为一个基础,无论怎样都要或多或少的了解一些,然后在逐步走向MFC,尽管是这样,不难发现后一种方法是前一种方法的改进,有一种逐步提高的感觉,MFC是对API的一种封装而已,给程序开发带来了巨大的方便。
有一本书《Windows程序设计》可以说是一本经典之作,我想很多人都有这套书,书上第一个完整的例子就是Hello,world,一个简单的窗体,有着Windows窗体的一般特征,但是写了很多代码。但是学完了Pascal语法,使用Delphi进行Windows程序设计好像是一下子就跳到了使用VCL,对于什么消息循环,消息处理,丝毫没有涉及到,很多参考书也没有提到这些,对于我的感觉好像就是C/C++天生就是用来开发Windows程序的,无缝连接,Pascal的语法是有一点怪怪的,好像不适合(一开始给我的感觉就是不可以)配合SDK进行Windows程序开发,后来查了一点资料,逐渐摸索,找到了一点眉目,希望能够和大家共同进步。这个例子可以说是Charles例子的一个克隆,只是语法换成了Pascal而已,在这里也同样有消息循环,消息处理,等等。下面给出这个程序的具体代码还有详细的注释,为了阅读的关系我分成了几个处理函数,都有特殊的注明。
具体开始的时候也是new一个Application然后关掉默认给我们加的窗口还有代码窗口当显示提示是否要保存的时候选择否,然后在project中选择view source选项,跳到代码窗口,修改其中代码。
program Project2;
uses
Windows,
Messages;
var
Msg:TMsg;
wc:TWndClass; //RegisterClass()所需要的参数
hWnd:THandle; //主窗体的句柄
const
ClassName='MainWClass';
OutText='Hello ';
Function MainWndProc(Handle:THandle;MsgID:UINT;wParam,lParam:Integer):LRESULT;stdcall;
var
pDC:HDC;
lpRect:TRECT;
begin
Result:=1;
case MsgID of
WM_CLOSE:
begin //关闭窗体所产生的消息
if MessageBox(Handle,'要关闭这个程序吗?','程序示例',MB_ICONQUESTION or MB_YESNO)=IDYES then
DestroyWindow(hWnd)
else
Result:=0;
Exit;
end;
WM_DESTROY: //DestroyWindow()所产生的消息
begin
PostQuitMessage(0);
end;
WM_PAINT:
begin
pDC:=GetDC(hWnd);
GetClientRect(hWnd,lpRect);
DrawText(pDC,OutText,5,lpRect,DT_SINGLELINE or DT_CENTER or DT_VCENTER);
//TextOut(pDC,10,10,OutText,5);
ReleaseDC(hWnd,pDC);
end;
end;
//剩下的消息交给Windows预设的处理函数就可以了,比如画窗体的WM_NCPAINT消息等等
Result:=DefWindowProc(Handle,MsgID,wParam,lParam);
end;
//初始化,注册窗口类
Function InitApplication(hInstance:THANDLE):Boolean;
begin
//首先使用RegisterClass()注册窗体类,这可不是Delphi数据类型中的类哦
wc.style:=CS_HREDRAW OR CS_VREDRAW;
wc.lpfnWndProc:=@MainWndProc; //消息处理函数的地址
wc.hInstance:=hInstance; //程序的句柄,同时也是基地址
wc.hIcon:=LoadIcon(0,PChar(IDI_APPLICATION));
wc.hCursor:=LoadCursor(0,IDC_ARROW); //图标
wc.hbrBackground:=GetStockObject(WHITE_BRUSH); //背景画刷
wc.lpszClassName:=ClassName; //前面定义的常量
Result:=Boolean(RegisterClass(wc));//注册这个窗口类
end;
//InitInstance 生成窗口
Function InitInstance(hInstance:THANDLE;nCmdShow:Integer):Boolean;
begin
hWnd:=CreateWindowEx(0,
ClassName, //刚才注册的类的名字
'示例', //窗体的标题
WS_OVERLAPPEDWINDOW, //窗体的类型,有标题栏、系统菜单、最大化最小化菜单,以及拉伸边框
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
0,
0,
hInstance,
nil
);
if hWnd=0 then
begin
Result:=false;
Exit;
end;
ShowWindow(hWnd,CmdShow);
UpdateWindow(hWnd);
Result:=true;
end;
//主程序开始
begin
if Not InitApplication(hInstance) then Halt(0); //初始化注册窗口类
if Not InitInstance(hInstance,CmdShow) then Halt(0); //产生窗口
while GetMessage(Msg,0,0,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg); //该API将消息分派到相应的窗体消息处理函数
end;
ExitCode:=Msg.wParam;
end.
上面给出了详细的代码,其中借鉴了有关文章,这就是最基本的框架,如果使用C进行过Windows程序开发的话,会对上面的代码非常熟悉,不错确实是大同小异,只是很多变量的定义和写法有点差别,还有就是函数调用时候有一些注意点。
我比较喜欢和大家一起讨论,喜欢追究个所以然,希望各位能够和我一起讨论,一起进步。