Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!wuarchive!uunet!lotus!lotus.com!robertk From: robertk@lotatg.lotus.com (Robert Krajewski) Newsgroups: comp.windows.ms.programmer Subject: Re: Associating window handle with C++ object Message-ID: Date: 25 Apr 91 14:41:47 GMT References: <0J7H11w163w@burklabs> <1991Apr18.182959.11263@SanDiego.NCR.COM> Sender: news@lotus.com Organization: /homes/robertk/.organization Lines: 105 In-Reply-To: davel@booboo.SanDiego.NCR.COM's message of 18 Apr 91 18:29:59 GMT In article <1991Apr18.182959.11263@SanDiego.NCR.COM> davel@booboo.SanDiego.NCR.COM (David Lord) writes: I didn't like the tecnique used in whello.cpp. Seems to me their use of classes serves only to make the program more complicated and doesn't give coresponding benifits (reusibility, etc.) Ultimately I used a separate window proc for each window. Sorry, but this doesn't follow. The whole reason for using C++ is to STOP using manual forms of inheritance, like Windows WNDPROCs, and start using a unified paradigm in the language. The most compelling reason for minimizing the proliferation of WNDPROCs is that every new window class must be manually initialized with RegisterClass. That is bookkeepping that is error-prone. Instead of using extra bytes for storing a pointer in the extra window bytes, I use a more flexible (albeit slightly less efficient) scheme. By using properties instead of extra bytes, you don't depend on how many extra window bytes any associated Windows window uses, which means that you can use this association scheme for your own windows and dialogs (which have DLGWNDEXTRA extra bytes). Since properties can only hold a WORD's worth of information, the property value will either have to be a NEAR pointer (if you are using medium model) or an index into a table, each of whose elements is a pointer to the C++ window. Assuming medium model (the work for table maintenance complicates matters), I'd get something like this (just for illustrative purposes): Caveats: I've never used Borland, but this still will work with Zortech; no special provisions for MDI, CS_HREDRAW, CS_VREDRAW, class icons. class Window { friend LONG FAR PASCAL WindowDispatcherProc(HWND, WORD, WORD, LONG); public: Window(); // Constructor HWND Realize(); // Make a real MSW window. Returns what CreateWindow returns HWND GetHandle() const { return fHandle; } virtual LONG HandleMessage(WORD wMsg, WORD wParam, LONG lParam); // Handle the message, following WNDPROC protoco. static Window * WindowFromHandle(HWND hWnd); private: WORD fHandle; // Real window handle }; /* --- Implementation --- */ static const char kWindowProp[] = "Window"; // Property tag static const char kWindowClass[] = "Window_CLASS"; // Class tag << need to register kWindowClass with WindowDispatcherProc >> Window::Window() : fHandle(0) { } Window * Window::WindowFromHandle(HWND hWnd) { WORD prop = GetProp(hWnd, kWindowProp); return (Window *)prop; } HWND Window::Realize() { return CreateWindow(kWindowClass, ... lParam is (LONG)this); } LONG Window::HandleMessage(WORD wMsg, WORD wParam, LONG lParam) { return DefWindowProc(GetHandle(), wMsg, wParam, lParam); } LONG FAR PASCAL WindowDispatcherProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) { Window * w; switch (wMsg) { case WM_NCCREATE: // just let it go return DefWindowProc(hWnd, wMsg, wParam, lParam); break; case WM_CREATE: // do association w = (Window *)((LPCREATESTRUCT)lParam)->lpCreateParams; SetProp(hWnd, kWindowProp, (HANDLE)w); // pointer is property w->fHandle = hWnd; // Give class a chance to handle WM_CREATE return w->HandleMessage(wMsg, wParam, lParam); break; default: // Still possible that window wasn't associated w = WindowFromHandle(hWNd); if (w) return w->HandleMessage(wMsg, wParam, lParam); else return DefWindowProc(hWnd, wParam, lParam); break; } }