I have read several articles about comparing VC and Delphi, and I am also interested in writing code to try it out. I have built a new project under VC6 called WinTest. The code is as follows:
#include <windows.h>
HWND hwndButton;
int cx, cy;
LRESULT CALLBACK MainWndPRoc (HWND hWindow, UINT nMsg, WPARAM wPrm, LPARAM lPrm)
{
HDC dc;
PAINTSTRUCT ps;
RECT rc;
switch (nMsg)
{
case WM_CREATE:
{
TEXTMETRIC tm;
dc = GetDC (hWindow);
SelectObject (dc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (dc, &tm);
cx = tm.tmAveCharWidth * 30;
cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
ReleaseDC (hWindow, dc);
hwndButton = CreateWindow (
"button",
"Click Here",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0, 0, cx, cy,
hWindow,
(HMENU) 1,
((LPCREATESTRUCT) lPrm)->hInstance,
NULL
);
return 0;
break;
}
case WM_DESTROY:
{
PostQuitMessage (0);
return 0;
break;
}
case WM_PAINT:
{
dc = BeginPaint (hWindow, &ps);
GetClientRect (hWindow, &rc);
rc.bottom = rc.bottom / 2;
DrawText (dc, "Hello, World!", -1, &rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hWindow, &ps);
return 0;
break;
}
case WM_SIZE:
{
if (hwndButton && (wPrm == SIZEFULLSCREEN ||wPrm == SIZENORMAL))
{
rc.left = (LOWord(lPrm) - cx) / 2;
rc.top = HIWORD(lPrm) * 3 / 4 - cy / 2;
MoveWindow (hwndButton,rc.left, rc.top, cx, cy, TRUE);
}
return 0;
break;
}
case WM_COMMAND:
{
if (LOWORD(wPrm) == 1 && HIWORD(wPrm) == BN_CLICKED &&
(HWND) lPrm == hwndButton)
{
DestroyWindow (hWindow);
}
return 0;
break;
}
}
return DefWindowProc (hWindow, nMsg, wPrm, lPrm);
}
//winmain
int __stdcall WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
HWND hWindowMain;
MSG MyMsg;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= (WNDPROC)MainWndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInst;
wcex.hIcon= LoadIcon (NULL, IDI_application);
wcex.hCursor= LoadCursor (NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszClassName= "WinTestWin";
wcex.hIconSm= LoadIcon (NULL, IDI_APPLICATION);
RegisterClassEx (&wcex);
hWindowMain = CreateWindow (
"WinTestWin",
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
hInst,
NULL
);
ShowWindow (hWindowMain, nShow);
UpdateWindow (hWindowMain);
While (GetMessage (&MyMsg, 0, 0, 0))
{
TranslateMessage (&MyMsg);
DispatchMessage (&MyMsg);
}
return MyMsg.wParam;
}
Select Release to compile, turn on the minimum code optimization of VC6, and the execution code generated by the compile is 36.0KB.
Then translate it into Delphi code as follows:
program WinTest;
uses
Windows,Messages;
var
hwndButton:HWND;
cx,cy:Integer;
function MainWndProc (hWindow:HWND;nMsg:UINT;wPrm:WPARAM;lPrm:LPARAM):LRESULT;stdcall;
var
dc:HDC;
ps:PAINTSTRUCT;
rc:TRect;
tm:TEXTMETRIC;
pctst:PCREATESTRUCT;
Begin
case nMsg of
WM_CREATE:
Begin
dc := GetDC (hWindow);
SelectObject (dc, GetStockObject (SYSTEM_FIXED_FONT));
GetTextMetrics (dc, tm);
cx := tm.tmAveCharWidth * 30;
cy := (tm.tmHeight + tm.tmExternalLeading) * 2;
ReleaseDC (hWindow, dc);
pctst:= PCREATESTRUCT(lPrm);
hwndButton := CreateWindow(
'button',
'Click Here',
WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON,
0, 0, cx, cy,
hWindow,
HMENU(1),
pctst^.hInstance,
nil
);
Results:=0;
Exit;
end;
WM_DESTROY:
Begin
PostQuitMessage(0);
Results:=0;
Exit;
end;
WM_PAINT:
Begin
dc := BeginPaint (hWindow, ps);
GetClientRect (hWindow, rc);
rc.bottom := Round(rc.bottom / 2);
DrawText (dc, 'Hello, World!', -1, rc,
DT_SINGLELINE or DT_CENTER or DT_VCENTER);
EndPaint (hWindow, ps);
Results:= 0;
Exit;
end;
WM_SIZE:
Begin
if (hwndButton<>0) and (wPrm = SIZEFULLSCREEN) or (wPrm = SIZENORMAL) then
Begin
rc.left := Round((LOWORD(lPrm) - cx) / 2);
rc.top := Round(HIWORD(lPrm) * 3 / 4 - cy / 2);
MoveWindow (hwndButton,rc.left, rc.top, cx, cy, True);
end;
Results:= 0;
Exit;
end;
WM_COMMAND:
Begin
if (LOWORD(wPrm) = 1) and (HIWORD(wPrm) = BN_CLICKED) and
(HWND(lPrm) = hwndButton) then
Begin
DestroyWindow (hWindow);
end;
Results:= 0;
Exit;
end;
end;
Result:=DefWindowProc (hWindow, nMsg, wPrm, lPrm);
end;
//winmain
var
hWindowMain:HWND;
MyMsg:MSG;
wcex:WNDCLASSEX;
Begin
wcex.cbSize := SizeOf(WNDCLASSEX);
wcex.style := CS_HREDRAW or CS_VREDRAW;
wcex.lpfnWndProc := @MainWndProc;
wcex.cbClsExtra:= 0;
wcex.cbWndExtra:= 0;
wcex.hInstance := MainInstance;
wcex.hIcon := LoadIcon (0, IDI_APPLICATION);
wcex.hCursor := LoadCursor (0, IDC_ARROW);
wcex.hbrBackground := HBRUSH(COLOR_WINDOW+1);
wcex.lpszClassName := 'WinTestWin';
wcex.hIconSm := LoadIcon (0, IDI_APPLICATION);
RegisterClassEx (wcex);
hWindowMain := CreateWindow (
'WinTestWin',
'Hello',
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
MainInstance,
nil
);
ShowWindow (hWindowMain, CmdShow);
UpdateWindow (hWindowMain);
while GetMessage (MyMsg, 0, 0, 0)=True do
Begin
TranslateMessage (MyMsg);
DispatchMessage (MyMsg);
end;
end.
Finally, it was found that the code generated by Delphi was only 16.5k, which was more than half smaller than VC. This shows that Delphi has a good compiler, and VCL visualization function should be a good development tool. In my opinion, Delphi has no problem in developing large systems, and its performance may even exceed VC. It is just that the high packaging level of VCL makes programs that use VCL usually large, but the development efficiency is not comparable to that of VC. Delphi can also not use VCL to write programs. For example, someone online translated the source code of Quake2 into Delphi, and the effect is almost the same as that of C.