|
Wondering about KOL? Want to know how to use it? Here's a quick taste of what's to come: Ever wondered why the VCL always seems to give you at least a 400K executable, even if you were just writing a small utility? You probably know that when you go down to the bare metal and write your utility in plain WIN32 API, you can get your program down to just a couple of Kb. But if you know that, you know it's pretty hard to do. As an introduction I will present you with three programs that do all the same thing:nothing! First, the Delphi way: Just open Delphi (any version) and hit F9. You will get the famous Project1.exe which is - depending on the Delphi version you are using - between 200Kb and 400Kb. Nothing to it, hit F9, obtain a working Windows program. Doesn't do too much...you think! Now let's explain a bit what is done for you by writing something that is about the same thing in plain WIN32 API programming: Hardcore Win32 API Version program Hardcore; // // purpose: Hardcore API delphi program // author: This version © 2004, Thaddy de Koning // Based on a code example from John Ayres // In: The Tomes of Delphi, Win32 Core Api Win2000 edition uses Windows, Messages; -
// A Window function, dispatches the messages for our program function WindowProc(TheWindow: HWnd; TheMessage, WParam, LParam: Longint): Longint; stdcall; begin case TheMessage of // If we receive a WM_DESTROY message , // we quit the program WM_DESTROY: begin PostQuitMessage(0); Exit; end; end; -
// Call the default (os) window procedure for all messages // we don't handle ourselves Result := DefWindowProc(TheWindow, TheMessage, WParam, LParam); end; -
// This function registers the Window Class function RegisterClass: Boolean; var WindowClass: TWndClass; begin //Prepare our new window class windowClass.Style := CS_HREDRAW or CS_VREDRAW; // The Style -
windowClass.lpfnWndProc := @WindowProc; // The window procedure as defined above -
windowClass.cbClsExtra := 0; // No extra memory needed for the class -
windowClass.cbWndExtra := 0; // No extra memory needed for the window itself -
windowClass.hInstance := hInstance; // Application instance -
windowClass.hIcon := LoadIcon(0, IDI_APPLICATION); // Use a standard logo -
windowClass.hCursor := LoadCursor(0, IDC_UPARROW); // Use a standard cursor -
windowClass.hbrBackground := COLOR_BTNSHADOW; // Use a standard color -
windowClass.lpszMenuName := nil; // No menu, except for the system menu -
windowClass.lpszClassName := 'BlueAura'; // Thee registered class name -
//Registrer the class in the system} Result := Windows.RegisterClass(WindowClass) <> 0; end; -
var TheMessage: TMsg; OurWindow: HWND; begin // register the new class first if not RegisterClass then begin MessageBox(0,'RegisterClass failed',nil,MB_OK); Exit; end; -
// OurWindow := CreateWindowEx(0, {no extended styles} 'BlueAura', // Windows registered class name 'Project1', // Caption WS_OVERLAPPEDWINDOW or //normal screen WS_VISIBLE, // visible CW_USEDEFAULT, // horizontal position CW_USEDEFAULT, // vertical position CW_USEDEFAULT, // standard width CW_USEDEFAULT, // standard height 0, // geen ouders 0, // geen menu hInstance, // instance of our application nil // Nothing further ); -
// If it doesn't work, quit! if OurWindow=0 then begin MessageBox(0,'Phew, lukt niet...',nil,MB_OK); Exit; end; -
// This runs the actual program: while GetMessage(TheMessage,0,0,0) do begin TranslateMessage(TheMessage); DispatchMessage(TheMessage); end; -
end.
program%20Hardcore%3B%0A%2F%2F%0A%2F%2F%20purpose%3A%20Hardcore%20API%20delphi%20program%0A%2F%2F%20author%3A%20This%20version%20%26copy%3B%202004%2C%20Thaddy%20de%20Koning%0A%2F%2F%20Based%20on%20a%20code%20example%20from%20John%20Ayres%0A%2F%2F%20In%3A%20The%20Tomes%20of%20Delphi%2C%20Win32%20Core%20Api%20Win2000%20edition%0Auses%0AWindows%2C%20Messages%3B%0A%20%0A%2F%2F%20A%20Window%20function%2C%20dispatches%20the%20messages%20for%20our%20program%0Afunction%20WindowProc%28TheWindow%3A%20HWnd%3B%20TheMessage%2C%20WParam%2C%0ALParam%3A%20Longint%29%3A%20Longint%3B%20stdcall%3B%0Abegin%0Acase%20TheMessage%20of%0A%2F%2F%20If%20we%20receive%20a%20WM_DESTROY%20message%20%2C%0A%2F%2F%20we%20quit%20the%20program%0AWM_DESTROY%3A%0Abegin%0APostQuitMessage%280%29%3B%0AExit%3B%0Aend%3B%0Aend%3B%0A%20%0A%2F%2F%20Call%20the%20default%20%28os%29%20window%20procedure%20for%20all%20messages%20%0A%2F%2F%20we%20don%27t%20handle%20ourselves%0AResult%20%3A%3D%20DefWindowProc%28TheWindow%2C%20TheMessage%2C%20WParam%2C%20LParam%29%3B%0Aend%3B%0A%20%0A%2F%2F%20This%20function%20registers%20the%20Window%20Class%0Afunction%20RegisterClass%3A%20Boolean%3B%0Avar%0AWindowClass%3A%20TWndClass%3B%0Abegin%0A%2F%2FPrepare%20our%20new%20window%20class%0AwindowClass.Style%20%3A%3D%20CS_HREDRAW%20or%20CS_VREDRAW%3B%0A%2F%2F%20The%20Style%0A%20%0AwindowClass.lpfnWndProc%20%3A%3D%20%40WindowProc%3B%0A%2F%2F%20The%20window%20procedure%20as%20defined%20above%0A%20%0AwindowClass.cbClsExtra%20%3A%3D%200%3B%0A%2F%2F%20No%20extra%20memory%20needed%20for%20the%20class%0A%20%0AwindowClass.cbWndExtra%20%3A%3D%200%3B%0A%2F%2F%20No%20extra%20memory%20needed%20for%20the%20window%20itself%0A%20%0AwindowClass.hInstance%20%3A%3D%20hInstance%3B%0A%2F%2F%20Application%20instance%0A%20%0AwindowClass.hIcon%20%3A%3D%20LoadIcon%280%2C%20IDI_APPLICATION%29%3B%0A%2F%2F%20Use%20a%20standard%20logo%0A%20%0AwindowClass.hCursor%20%3A%3D%20LoadCursor%280%2C%20IDC_UPARROW%29%3B%0A%2F%2F%20Use%20a%20standard%20cursor%0A%20%0AwindowClass.hbrBackground%20%3A%3D%20COLOR_BTNSHADOW%3B%0A%2F%2F%20Use%20a%20standard%20color%0A%20%0AwindowClass.lpszMenuName%20%3A%3D%20nil%3B%0A%2F%2F%20No%20menu%2C%20except%20for%20the%20system%20menu%0A%20%0AwindowClass.lpszClassName%20%3A%3D%20%27BlueAura%27%3B%0A%2F%2F%20Thee%20registered%20class%20name%0A%20%0A%2F%2FRegistrer%20the%20class%20in%20the%20system%7D%0AResult%20%3A%3D%20Windows.RegisterClass%28WindowClass%29%20%3C%3E%200%3B%0Aend%3B%0A%20%0Avar%0ATheMessage%3A%20TMsg%3B%0AOurWindow%3A%20HWND%3B%0Abegin%0A%2F%2F%20register%20the%20new%20class%20first%0Aif%20not%20RegisterClass%20then%0Abegin%0AMessageBox%280%2C%27RegisterClass%20failed%27%2Cnil%2CMB_OK%29%3B%0AExit%3B%0Aend%3B%0A%20%0A%2F%2F%20%0AOurWindow%20%3A%3D%20CreateWindowEx%280%2C%20%7Bno%20extended%20styles%7D%0A%27BlueAura%27%2C%20%2F%2F%20Windows%20registered%20class%20name%0A%27Project1%27%2C%20%2F%2F%20Caption%0AWS_OVERLAPPEDWINDOW%20or%20%2F%2Fnormal%20screen%0AWS_VISIBLE%2C%20%2F%2F%20visible%0ACW_USEDEFAULT%2C%20%2F%2F%20horizontal%20position%0ACW_USEDEFAULT%2C%20%2F%2F%20vertical%20position%0ACW_USEDEFAULT%2C%20%2F%2F%20standard%20width%0ACW_USEDEFAULT%2C%20%2F%2F%20standard%20height%0A0%2C%20%2F%2F%20geen%20ouders%0A0%2C%20%2F%2F%20geen%20menu%0AhInstance%2C%20%2F%2F%20instance%20of%20our%20application%0Anil%20%2F%2F%20Nothing%20further%0A%29%3B%0A%20%0A%2F%2F%20If%20it%20doesn%27t%20work%2C%20quit%21%0Aif%20OurWindow%3D0%20then%0Abegin%0AMessageBox%280%2C%27Phew%2C%20lukt%20niet...%27%2Cnil%2CMB_OK%29%3B%0AExit%3B%0Aend%3B%0A%20%0A%2F%2F%20This%20runs%20the%20actual%20program%3A%0Awhile%20GetMessage%28TheMessage%2C0%2C0%2C0%29%20do%0Abegin%0ATranslateMessage%28TheMessage%29%3B%0ADispatchMessage%28TheMessage%29%3B%0Aend%3B%0A%20%0Aend. Now, this does the same, looks almost the same, but took a lot of work I hope you'll agree. But it is only a couple of Kb big, maybe 8-12Kb, again depending on the Delphi version, a possible saving of some 2000%! You should also be able to notice that it loads a lot faster and feels a lot snappier. But then again, this way of coding is tedious and really no fun at all once you've done it once or twice. Wouldn't it be nice if we had the comfort of the VCL with the small executable size of the hardcore way of doing things? That is where the Key Objects Library comes in: It does just that. First you need the KOL library available from http://bonanzas.rinet.ru/kol.zip. Unzip it to a new directory and then create this program: KOL Version program firstkol; -
uses windows, kol; -
-
begin applet:=Newform(nil,'Project1'); Run(Applet); end.
program%20firstkol%3B%0A%20%0Auses%0Awindows%2C%20kol%3B%0A%20%0A%20%0Abegin%0Aapplet%3A%3DNewform%28nil%2C%27Project1%27%29%3B%0ARun%28Applet%29%3B%0Aend. If you compile and run it, you'll see it does the same as the above, with less lines of code than even the VCL version autogenerated for you and that it is only about 24Kb in executable size. And it can become even better:
- KOL's MCK add-on allows you to design in much the same way as with the VCL
- If you use tweaked system.pas replacements the executable size will go down to only 12Kb.
I will write about those two features the next time. Have fun, Thaddy de Koning
|