module app; import win32.api; class MyFrame: public Frame { Panel panel; this() { super(); this.position(200,200); panel = new Panel(1,this); panel.position(10,10); panel.size(400,300); panel.keyDown = &onKeyDown; } void onKeyDown(WPARAM wParam) { // implementation of event } } void main() { MyFrame frm = new MyFrame(); frm.run(); } //-------------------------------------------------------------------------------------------------------- class Frame { int width = 640; // main window width int height = 480; // main window height int x = 0; // main window initial position int y = 0; HWND hWnd; // Holds Our Window Handle HINSTANCE hInst; // Holds The Instance Of The Application DWORD dwStyle; // Window Style this() { createWindow(); } void createWindow() { WNDCLASS wc; hInst = GetModuleHandleA(null); wc.lpszClassName = "DWndProc"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = &WindowProc; wc.hInstance = hInst; wc.hIcon = LoadIconA(null, IDI_APPLICATION); wc.hCursor = LoadCursorA(null, IDC_ARROW); wc.hbrBackground = GetStockObject(GRAY_BRUSH); ; wc.lpszMenuName = null; wc.cbClsExtra = wc.cbWndExtra = 0; assert(RegisterClassA(&wc)); // register parent dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style // get window handle hWnd = CreateWindowA(cast(LPCSTR)"DWndProc",cast(LPCSTR)"Window", dwStyle | WS_CLIPSIBLINGS |WS_CLIPCHILDREN|WS_THICKFRAME |WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE ,x,y,width, height, null, null, hInst, null); assert(hWnd); } public void position(int x,int y) { this.x = x; this.y = y; MoveWindow(hWnd,x,y,width,height,true); } public void size(int width,int height) { this.width = width; this.height = height; MoveWindow(hWnd,x,y,width,height,true); } void run() { MSG msg; bit done = false; while (!done) { if (PeekMessageA(&msg,null,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=true; // If So done=TRUE } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessageA(&msg); // Dispatch The Message } } } } extern(Windows) static int WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: { PostQuitMessage(0); break; } default: break; } return DefWindowProcA(hWnd, uMsg, wParam, lParam); } } //---------------------------------------------------------------------------------------------------- class Panel { Frame parent; // child's parent HMENU childID; int width = 100 ; // child width int height = 100 ; // child height int x = 0; // child position within parent int y = 0; HWND hWnd; // Holds Our Window Handle void delegate(WPARAM) keyDown; // to hold pointer to method that implements message handler this(int childID, Frame parent) { this.childID = cast(HMENU) childID; this.parent = parent; createWindow(); } void createWindow() { WNDCLASS wc; wc.lpszClassName = "Panel"; wc.lpfnWndProc = &WndProc; // window procedure wc.hIcon = null; wc.cbWndExtra = 8; wc.hbrBackground = GetStockObject(LTGRAY_BRUSH); assert(RegisterClassA(&wc)); // register child // create child window hWnd = CreateWindowA(cast(LPCSTR)"Panel",cast(LPCSTR)"Window", WS_CHILDWINDOW | WS_VISIBLE ,x,y,width,height, parent.hWnd, childID, parent.hInst, null); assert(hWnd); SetWindowLong(hWnd,GWL_USERDATA,cast(LONG)cast(void*) this); // remember this for Panel class } extern(Windows) static int WndProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { Panel objectPtr = cast(Panel)cast(void*) GetWindowLong(hWnd,GWL_USERDATA); assert(objectPtr); objectPtr.messageHandler(hWnd, uMsg, wParam, lParam); return DefWindowProcA(hWnd, uMsg, wParam, lParam); } void messageHandler(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_PAINT: { static char[] text = "D does Windows"; PAINTSTRUCT ps; HDC dc = BeginPaint(hWnd, &ps); RECT r; GetClientRect(hWnd, &r); HFONT font = CreateFontA(80, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); HGDIOBJ old = SelectObject(dc, cast(HGDIOBJ) font); SetTextAlign(dc, TA_CENTER | TA_BASELINE); TextOutA(dc, r.right / 2, r.bottom / 2, text, text.length); SelectObject(dc, old); EndPaint(hWnd, &ps); break; } case WM_KEYDOWN: { keyDown(wParam); break; } default: break; } } public void position(int x,int y) { this.x = x; this.y = y; MoveWindow(hWnd,x,y,width,height,true); } public void size(int width,int height) { this.width = width; this.height = height; MoveWindow(hWnd,x,y,width,height,true); } }