I am developing a controller program for multimedia keyboards. The actual controller (which will work in the background all the time) is going to be a simple API-based program (written in the DPR file, no forms unit), which loads a keyboard hook DLL & responds to its messages. Since I'm not very familiar with this way of programming, first I made it in a normal applcation, which worked fine. Then I made a simple API-based program from scratch which just displayed an empty window. No problems yet. Then I inserted the DLL loading/unloading and message handling parts. It works, but when I close the window (either with the [X] on the title bar or pressing the "stop" key which makes the program to exit message loop), it causes an invalid page fault in kernel32.dll. I tried to locate where the problem is, and found that it does not appear until the "End." line is reached. Also no problem if I do not load the DLL. I have absolutely no clue where the problem can be. Any idea?

---------- The source code: ----------

program testhook;
uses windows, messages;
{$R *.res}
const
HOOKLIBNAME = 'keyhook.dll';
WM_KEYHOOKMSG = WM_USER+303;

var
wClass: TWndClass;
Msg: TMsg;
wnd:hwnd;
q:boolean;

function Hook_Start(WinHandle : HWND; MsgToSend : integer) : boolean;
stdcall external HOOKLIBNAME name 'KeyboardHook_Start';

function Hook_Stop : boolean;
stdcall external HOOKLIBNAME name 'KeyboardHook_Stop';

function WindowProc(hWnd,Msg,wParam,lParam:Integer):Integer; stdcall;
begin
if Msg = WM_DESTROY then PostQuitMessage(0);
Result := DefWindowProc(hWnd,Msg,wParam,lParam);
end;

begin
wClass.lpszClassName:= 'CN';
wClass.lpfnWndProc := @WindowProc;
wClass.hInstance := hInstance;
wClass.hbrBackground:= 1;
wClass.hIcon := LoadIcon(hInstance,'MAINICON');
wClass.hCursor := LoadCursor(0,IDC_ARROW);
RegisterClass(wClass);

wnd:=CreateWindow(wClass.lpszClassName,'Title Bar',
WS_OVERLAPPEDWINDOW or WS_VISIBLE,
10,10,340,220,0,0,hInstance,nil);

Hook_start(wnd,wm_keyhookmsg); // If I comment this out, there is no problem (except the program does not receive the keystrokes)

while (GetMessage(Msg,0,0,0)) and not q do begin
DispatchMessage(Msg);
if (Msg.Message=wm_keyhookmsg) and (msg.lParam and 16711680 div 65536=105) then q:=true;
end;

Hook_Stop; //Returns true, it seems to be performed successfully

// If you insert a messagebox here, you have to click OK before the problem occurs

end.