незванный гость писал(а):
: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 тока один раз передается - при создании окна... Криво, елки-палки, я думал - есть решения получше...