Delphi XE8环境下使用windows下API函数创建一个空白窗口,类似于VS创建一个空白的Win32 Project。同样代码也借鉴于VS创建的空白的Win32 Project。
代码如下:
program Project1;
uses
Winapi.Windows,
Winapi.Messages;
function MyKeyDown(const Key : Integer): Boolean;
begin
Result := GetAsyncKeyState(Key) <> 0;
end;
//callback fucntion
//process the messages
function MyWndProc(hW: HWnd; messages: UInt; wParams: WPARAM; lParams: LPARAM): LRESULT; stdcall;
var
ps : PAINTSTRUCT;
local_hdc : HDC;
begin
Result := 0;
case messages of
WM_COMMAND:
begin
end;
WM_PAINT:
begin
local_hdc := BeginPaint(hW, ps);
EndPaint(hW, ps);
end;
WM_DESTROY:
begin
PostQuitMessage(0);
end
else
Result := DefWindowProc(hW, messages, wParams, lParams);
end;
end;
function MyRegisterClass(hInst : HINST): WORD;
var
wclass: TWndClassExW;
begin
//Don't forget to set all the properties, or you will failed to register
//you can use Structure 'TWndClassW' and register with function 'RegisterClassW'
wclass.cbSize := SizeOf(WNDCLASSEXW); //set size of this structure
wclass.style := CS_HREDRAW or CS_VREDRAW; //set style of general property of this form
wclass.lpfnWndProc := @MyWndProc; //callback function
wclass.cbClsExtra := 0;
wclass.cbWndExtra := 0;
wclass.hInstance := hInst; //set instance
wclass.hIcon := LoadIcon(0, IDI_APPLICATION);
wclass.hCursor := LoadCursor(0, IDC_ARROW);
wclass.hbrBackground := GetStockObject(WHITE_BRUSH);
wclass.lpszMenuName := nil;
wclass.lpszClassName := 'Project';
wclass.hIconSm := LoadIcon(wclass.hInstance, MAKEINTRESOURCE(0)); //set small icon
Result := RegisterClassExW(wclass);
end;
var
gbl_hW : HWND; //save window handle
function InitInstance(hInst : HINST; nCmdShow : Integer): Boolean;
var
hW : HWND;
begin
Result := False;
hW := CreateWindowW('Project', 'ProjectOne', WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInst, nil);
if hW <> 0 then
begin
ShowWindow(hW, nCmdShow);
UpdateWindow(hW);
gbl_hW := hW;
Result := True;
end;
end;
{$R *.res}
var
gbl_hInstance : HINST; //save instance of application
gbl_msg : MSG; //save the messages retrieved from the queues
begin
gbl_hInstance := GetModuleHandle(nil);
//you can also use global variables HInstance in DELPHI
//HInstance will be initialized in procedure _InitExe(see it in the unit SysInit)
//like: if RegisterClass(HInstance) = 0 then
if MyRegisterClass(gbl_hInstance) = 0 then
begin
MessageBox(0, 'RegisterClass Error', 'Error', MB_OKCANCEL);
Exit;
end;
if not InitInstance(gbl_hInstance, SW_SHOW) then
begin
MessageBox(0, 'InitInstance Error', 'Error', MB_OKCANCEL);
Exit;
end;
//GetMessage will be wait a msg
while GetMessage(gbl_msg, 0, 0, 0) do
begin
TranslateMessage(gbl_msg);
DispatchMessage(gbl_msg);
if MyKeyDown(VK_ESCAPE) then
SendMessage(gbl_hW, WM_CLOSE, 0, 0);
end;
//also
// while True do
// begin
// //PeekMessage will be returned immediately, so use while true
// if PeekMessage(gbl_msg, 0, 0, 0, PM_REMOVE) then
// begin
// if gbl_msg.message = WM_QUIT then
// Break;
//
// TranslateMessage(gbl_msg);
// DispatchMessage(gbl_msg);
// end;
// end;
end.
注意:注册Windows类的时候,Windows类的结构要与注册函数匹配,否者会造成注册失败。
var
wclass: TWndClassExW;
....
....
Result := RegisterClassExW(wclass);
同时所有的属性记得都要设置,否者也会导致注册失败。
注:结构TWndClassEx和结构TWndClassExW中,前者的类名成员(lpszClassName)、菜单名成员(lpszMenuName)定义为PAnsiChar,在Delphi2007中即为PChar;而后者的两个成员定义为PWideChar。
Delphi xe8使用的是Unicode编码,所以使用TWndClassExW没问题,Delphi 2007使用的是AnsiCode编码;使用TWndClassEx也没啥问题,但是混用的时候要注意了。