今、私はDelphiのSDK(VCLを使わない)でMDIウィンドウを作っています。
そこで、C言語のサンプルからDelphiに移植しようとしているのですが、
Delphiで作るとMDIウィンドウの挙動が変なのです。
http://wisdom.sakura.ne.jp/system/winapi/win32/win140.htmlのサンプル
を参考に移植しているのですが、ここのプログラムをbcc32(Cコンパイラ)で
コンパイルすると完全にうまく動くのですが、次のようにDelphiで書き直すと、
MDI子ウィンドウを最大化した後、上から2段目のシステムメニューが効かなくなったりして変です。
環境はWin2000+Delphi6Personalです。どこがおかしいのか教えていただければうれしいです。
program MDI;
uses Windows, Messages;
const
MDI_FRAME = 'FRAMEWINDOW';
MDI_CHILD = 'MDICHILD';
IDM_EXIT = $1001;
IDM_NEW = $2001;
ID_CHILDWND = $100;
var myMsg :MSG;
winc :WNDCLASS;
hClientWindow :HWND;
function FrameProc(hWnd :HWND; uMsg :UINT; wParam :WPARAM; lParam :LPARAM) :LRESULT; stdcall;
var ccsClient :CLIENTCREATESTRUCT;
begin
Result := 0;
if uMsg = WM_DESTROY then begin
PostQuitMessage(0);
end
else if uMsg = WM_COMMAND then begin
case (wParam and $FFFF) of
IDM_NEW :begin
CreateMDIWindow(MDI_CHILD, 'Kitty on your lap', 0, 0, 0, 200, 200, hClientWindow, HInstance, 0);
end;
IDM_EXIT :begin
SendMessage(hWnd, WM_CLOSE, 0, 0);
end;
end
end
else if uMsg = WM_CREATE then begin
ccsClient.hWindowMenu := GetSubMenu(GetMenu(hWnd) , 1);
ccsClient.idFirstChild := ID_CHILDWND;
hClientWindow := CreateWindowEx(0, 'MDIClient', nil, WS_CHILD or WS_CLIPCHILDREN or WS_VISIBLE, 0, 0, 0, 0, hWnd, 1, HInstance, @ccsClient);
end
else begin
Result := DefFrameProc(hWnd, hClientWindow, uMsg, wParam, lParam);
end;
end;
begin
{$R Test.res}
winc.style := CS_VREDRAW or CS_HREDRAW;
winc.lpfnWndProc := @FrameProc;
winc.cbClsExtra := 0;
winc.cbWndExtra := 0;
winc.hInstance := HInstance;
winc.hIcon := LoadIcon(0, IDI_WINLOGO);
winc.hCursor := LoadCursor(0, IDC_ARROW);
winc.hbrBackground := COLOR_APPWORKSPACE + 1;
winc.lpszMenuName := 'KITTY';
winc.lpszClassName := MDI_FRAME;
RegisterClass(winc);
winc.lpfnWndProc := @DefMDIChildProc;
winc.hbrBackground := COLOR_WINDOW + 1;
winc.lpszClassName := MDI_CHILD;
RegisterClass(winc);
CreateWindowEx(0, MDI_FRAME, 'Kitty on your lap', WS_OVERLAPPEDWINDOW or WS_VISIBLE, 0, 0, 500, 500, 0, 0, HInstance, 0);
while GetMessage(myMsg, 0, 0, 0) do begin
TranslateMessage(myMsg);
DispatchMessage(myMsg);
end;
end.
FrameProc の
Result := DefFrameProc(hWnd, hClientWindow, uMsg, wParam, lParam);
この部分は、メッセージ処理をしたときも実行してください。C の switch 文に
相当するのは Delphi の case 文です。
return DefFrameProc(hWnd , hClientWindow , msg , wp , lp);
の部分は switch 文の外にありますよね。
おおー、動きました。ついついDefWindowProcと同じように書いてしまいました。
思い込みはいけませんね。これのせいで半年も悩んでしまいました。
りおりおさん、本当にありがとうございました。
ツイート | ![]() |