Topic
Интересующийся
Offline
|
|
« : 18-08-2010 09:13 » |
|
Проблема в следующем: у меня есть класс, отвечающий за создание/рисование окна. Я хочу внести функцию обработки событий WndProc в мой класс. Ошибка при компиляции указывает на строку: KWnd mainWnd(TEXT("An application"), hInstance, nShowCmd, &KWnd::WndProc); Текст ошибки: cannot convert parameter 4 from 'LRESULT (__stdcall KWnd::* )(HWND,UINT,WPARAM,LPARAM)' to 'LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)'
Чего-то не соображу, как параметр привести к виду __stdcall KWnd::* может это вообще не так делается? Буду рад советам. main.cpp//#include <windows.h> #include "KWnd.h"
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
MSG msg; KWnd mainWnd(TEXT("An application"), hInstance, nShowCmd, &KWnd::WndProc);
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
return msg.wParam; } KWnd.h#include <windows.h>
void DrawNewPicture(HWND& hWnd,HDC& hMemDC,HBITMAP& hMemBMP);
class KWnd { public: KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow, LRESULT (WINAPI *pWndProc)(HWND, UINT, WPARAM, LPARAM), LPCTSTR menuname = NULL, int x = CW_USEDEFAULT, int y = 0, int width = CW_USEDEFAULT, int height = 0, UINT classStyle = CS_HREDRAW | CS_VREDRAW, DWORD windowStyle = WS_OVERLAPPEDWINDOW, HWND hParent = NULL);
// обработка сообщений: её в public или protected? LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND GetHWnd() { return hWnd; } protected: HWND hWnd; WNDCLASSEX wc;
};
KWnd::KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow, LRESULT (WINAPI *pWndProc)(HWND, UINT, WPARAM, LPARAM), LPCTSTR menuName, int x, int y, int width, int height, UINT classStyle, DWORD windowStyle, HWND hParent) { TCHAR szClassName[] = TEXT("KWndClass");
wc.cbSize = sizeof(wc); wc.style = classStyle; wc.lpfnWndProc = pWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = menuName; wc.lpszClassName = szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) { TCHAR msg[100] = TEXT("Cannot register class: "); wcscat_s(msg, 100, szClassName); MessageBox(NULL, msg, TEXT("Error"), MB_OK | MB_ICONERROR); return; }
// по умолчанию окно располагается по центру // и имеет фиксированную высоту/ширину if (x == CW_USEDEFAULT && width == CW_USEDEFAULT) { // получаем разрешение монитора (1024х768) int xFullScreen = GetSystemMetrics(SM_CXSCREEN); int yFullScreen = GetSystemMetrics(SM_CYSCREEN);
// размеры окна по умолчанию width = 720; height = 540;
// вычисляем позицию левого верхнего угла окна x = int(xFullScreen/2 - width/2); y = int(yFullScreen/2 - height/2); }
hWnd = CreateWindow(szClassName, windowName, windowStyle, x, y, width, height, hParent, (HMENU)NULL, hInst, NULL);
if (!hWnd) { TCHAR text[100] = TEXT("Cannot create window: "); wcscat_s(text, 100, szClassName); MessageBox(NULL, text, TEXT("Error"), MB_OK | MB_ICONERROR); return; }
ShowWindow(hWnd, cmdShow); UpdateWindow(hWnd); }
LRESULT CALLBACK KWnd::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HDC hMemDC=0; static HBITMAP hMemBMP=0; static bool bTimerOn=true;
// характеристики таймера enum { e_timer_id=0, // идентификатор e_timer_vl=10, // время в миллисекундах };
switch(uMsg) { case WM_CREATE: { DrawNewPicture(hWnd,hMemDC,hMemBMP); } break;
case WM_TIMER: { DrawNewPicture(hWnd,hMemDC,hMemBMP); } break;
case WM_RBUTTONDOWN: { if(bTimerOn=!bTimerOn) { KillTimer(hWnd,e_timer_id); } else { SetTimer(hWnd,e_timer_id,e_timer_vl,0); } } break;
case WM_PAINT: { PAINTSTRUCT ps; RECT rect;
HDC hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
// Теперь копируем растр из памяти на экран if(hMemDC && hMemBMP) { BitBlt(hDC, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY); } else { // отладочные команды (в случае ошибки) // если hMemDC или hMemBMP пуст, то рисуем одну линию // перечеркивающую экран MoveToEx(hDC,rect.left,rect.top,0); LineTo(hDC,rect.right,rect.bottom); }
EndPaint(hWnd, &ps); } break;
case WM_LBUTTONDOWN: { DrawNewPicture(hWnd,hMemDC,hMemBMP); } break;
case WM_DESTROY: { if(hMemBMP) { DeleteObject(hMemBMP); hMemBMP=0; }
if(hMemDC) { DeleteDC(hMemDC); hMemDC=0; }
PostQuitMessage(0); } break;
default: { return DefWindowProc(hWnd, uMsg, wParam, lParam); } break; }
return 0; }
// Функция рисования на форме // я её потом внесу в класс и уберу параметры, но это потом... // пока и так работает void DrawNewPicture(HWND& hWnd,HDC& hMemDC,HBITMAP& hMemBMP) { HPEN myPen = 0; int xrand = 0; int yrand = 0; int Rrand = 0; int Grand = 0; int Brand = 0; int iWidthRand = 0; int iStyleRand = 0;
// послать в очередь сообщений сообщение WM_PAINT о том, что нужно перерисовать окно InvalidateRect(hWnd,0,0);
// освободить память от предыдущего вызова if(hMemBMP) { DeleteObject(hMemBMP); hMemBMP = 0; }
if(hMemDC) { DeleteDC(hMemDC); hMemDC = 0; }
RECT rect; GetClientRect(hWnd, &rect);
{ HDC hDC = GetDC(hWnd); hMemDC = CreateCompatibleDC(hDC); hMemBMP = CreateCompatibleBitmap(hDC,rect.right-rect.left+1,rect.bottom-rect.top+1);
// освободить память от предыдущего вызова HBITMAP oldBMP = (HBITMAP)SelectObject(hMemDC,hMemBMP); if (oldBMP) DeleteObject(oldBMP);
ReleaseDC(hWnd, hDC); }
if(hMemDC && hMemBMP) { // рисуем что требуется MoveToEx(hMemDC, 50, 60, NULL);
for (int i=0; i<10; i++) { // позиция по х и у, куда проводить линию xrand = rand()%(rect.right-100)+50; yrand = rand()%(rect.bottom-100)+50;
// стиль (начертание) линии iStyleRand = rand()%7;
// толщина линии iWidthRand = rand()%7;
// цвет линии Rrand = rand()%256; Grand = rand()%256; Brand = rand()%256;
// создаем карандаш myPen = CreatePen(iStyleRand, iWidthRand, RGB(Rrand, Grand, Brand));
// выбираем наш карандаш SelectObject(hMemDC, myPen);
// нарисовать линию LineTo(hMemDC, xrand, yrand);
// освобождаем память из под созданного карандаша DeleteObject(myPen); } } }
|