незванный гость писал(а):
:evil: 
Не сказал бы, что Виндузе - пятизвездочный отель. Скорее трущобы...
Не, я бы хотел, что б моя библиотека классов на него (отель) смахивала...  

  Хотя возводить отели из того материала, что можно в трущобах найти - занятие неблагодарное...  
 
 
Вот реализация, что я в книжке нашел... 
Объявление класса:
Код:
class KWindow
{
protected:
   virtual void OnDraw(HDC hDC)
   {
   }
   virtual void OnKeyDown(WPARAM wParam, LPARAM lParam)
   {
   }    
   virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
   virtual void GetWndClassEx(WNDCLASSEX & wc);
   static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);   
   HRESULT CommonMDIChildProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
      HMENU hMenu, int nWindowMenu);
   HPALETTE m_hPalette;
   int       m_nUpdateCount;
   virtual LRESULT OnQueryNewPalette(void);
   virtual LRESULT OnPaletteChanged(HWND hWnd, WPARAM wParam);
   bool    m_bMainWindow;
public:
   HWND  m_hWnd;
   KWindow(void)
   {
      m_hWnd         = NULL;
      m_hPalette      = NULL;
      m_nUpdateCount = 0;
      m_bMainWindow  = false;
   }
   virtual ~KWindow(void)
   {
      if ( m_hPalette )
      {
         DeleteObject(m_hPalette);
         m_hPalette = NULL;
      }
   }    
   virtual bool CreateEx(DWORD dwExStyle, LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle, 
      int x, int y, int nWidth, int nHeight, HWND hParent, HMENU hMenu, HINSTANCE hInst);
   bool RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst);
   virtual WPARAM MessageLoop(void);
   BOOL ShowWindow(int nCmdShow) const
   {
      return ::ShowWindow(m_hWnd, nCmdShow);
   }
   BOOL UpdateWindow(void) const
   {
      return ::UpdateWindow(m_hWnd);
   }
};
Я приведу реализацию только двух функций - WndProc и WindowProc, думаю этого достаточно:
Код:
// Default message handler for main program window, dispatch to OnKeyDown, OnDraw, etc.
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch( uMsg )
   {
      case WM_KEYDOWN:
         OnKeyDown(wParam, lParam);
         return 0;
      case WM_PAINT:
        {
            PAINTSTRUCT ps;                 
            BeginPaint(m_hWnd, &ps);
            OnDraw(ps.hdc);
            EndPaint(m_hWnd, &ps);
        }
        return 0;
      case WM_PALETTEISCHANGING: // should not happen
         MessageBox(NULL, _T("Hello"), _T("Hi"), MB_OK);
         return 0;
      case WM_PALETTECHANGED:
         return OnPaletteChanged(hWnd, wParam);
      case WM_QUERYNEWPALETTE:
         return OnQueryNewPalette();
      case WM_DESTROY:
         if ( m_bMainWindow )
            PostQuitMessage(0); // main window only
         return 0;
   }
   return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// Generic window procedure passed to WIN32 API, dispatches to KWindow::WndProc
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   KWindow * pWindow;
        
   if ( uMsg==WM_NCCREATE )
   {   
      assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
      MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
      pWindow = (KWindow *) (pMDIC->lParam);
      assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
      SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
   }
   else
      pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
   if ( pWindow )
      return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
   else
      return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Да, setwindowslong & getwindowsling, но мало того -  указатель pwindow тока один раз передается - при создании окна... Криво, елки-палки, я думал - есть решения получше...