Fensterklassen Problem
-
Hi!
Ich habe eine Programm geschrieben, das ein Hauptfenster enthält.Die Window-Prozedur des Hauptdensters erstellt 25 Chldfnster, die alle gemeinsam eine Window-Prozedur bekommen.
ICh bekomme bei der erstellung des Hauptfensters immer eine merkwürdige Fehlermeldung des Compilers:
C:\Programme\Microsoft Visual Studio\MyProjects\sdfsdfsdfsdfsdferrsrdfs\dd.cpp(57) : error C2664: 'CreateWindowExA' : Konvertierung des Parameters 10 von 'struct HINSTANCE__ *' in 'struct HMENU__ *' nicht moeglich
Die Typen, auf die verwiesen wird, sind nicht verwandt; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
obwohl ich das Fenster immer so erstelle!Hier der Code:
#include <windows.h> #define DIVISIONS 5 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM); TCHAR ChildClass[] = TEXT("childclass"); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.lpfnWndProc = WndProc; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.hInstance = hInstance; wndclass.lpszClassName = TEXT("Hi"); wndclass.lpszMenuName = 0; RegisterClass(&wndclass); wndclass.cbClsExtra = sizeof(long); wndclass.lpfnWndProc = ChildWndProc; wndclass.lpszClassName = ChildClass; wndclass.hIcon = NULL; RegisterClass(&wndclass); hwnd = CreateWindow( TEXT("Hi"), TEXT("Treffer"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hInstance, NULL, NULL); ShowWindow(hwnd, nShowCmd); UpdateWindow(hwnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static HWND hwndChild[DIVISIONS][DIVISIONS]; static int cxBlock, cyBlock; int x, y; switch(message) { case WM_CREATE: for(x=0; x<DIVISIONS; ++x) { for(y=0; y<DIVISIONS; ++y) { hwndChild[x][y] = CreateWindow(ChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) (y << 8 | x), (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); } } return 0; case WM_SIZE: cxBlock = LOWORD(lParam)/DIVISIONS; cyBlock = HIWORD(lParam)/DIVISIONS; for(x=0; x<DIVISIONS; ++x) { for(y=0; y<DIVISIONS; ++y) { MoveWindow(hwndChild[x][y], cxBlock * x, cyBlock * y, cxBlock, cyBlock, true); } } return 0; case WM_LBUTTONDOWN: MessageBeep(0); case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch(message) { case WM_CREATE: SetWindowLong(hwnd, 0, 0); return 0; case WM_LBUTTONDOWN: SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0)); InvalidateRect(hwnd, NULL, FALSE); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); Rectangle(hdc, 0, 0, rect.right, rect.bottom); if(GetWindowLong(hwnd, 0)) { MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, rect.right, rect.bottom); MoveToEx(hdc, rect.right, 0, NULL); LineTo(hdc, 0, rect.bottom); } EndPaint(hwnd, &ps); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
-
Im ersten Aufruf gibst Du die HINSTANCE im dritten Parameter von hinten an. Im anderen Aufruf ist es der zweite von hinten. Dafür, daß Du das immer so machst, ist es doch ganz schön unterschiedlich.
-
ok danke!
Eine Frage habe ich noch!
Wenn man auf ein Child Fenster klickt sollte eigentlich ein "X" erscheinen und beim zweiten Klick sollte es dann verschwinden.
Aber bei mir erscheint kein X!
Was ist falsch?
-
Schau zuerst mal auf die Größe deines Childs. Und mit dem Verschwindwn des Kreuzes ist das auch so ne Sache... Hilfestellung: Erstell dir ne BOOL-Variable, die TRUE ist, wenn das Kreuz da ist, und FALSE, wenn nicht.
-
ICh habe jetzt versucht,das ganze mit ner Bool Variable zu lösen.Aber da kommt das Problem,das ich immer 2 mal auf jedes Child klicken muss,um ein Kreuz zu erzeugen bzw. um es verschwinden zu lassen.Also es komtm mir so vor,als würde sich der Status für alle Childs verändern, sobald ich eins anklicke!Wie löse ich das Prob?
Der neue COde:
#include <windows.h> #define DIVISIONS 5 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM); TCHAR ChildClass[] = TEXT("childclass"); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.lpfnWndProc = WndProc; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.hInstance = hInstance; wndclass.lpszClassName = TEXT("Hi"); wndclass.lpszMenuName = 0; RegisterClass(&wndclass); wndclass.cbClsExtra = sizeof(long); wndclass.lpfnWndProc = ChildWndProc; wndclass.lpszClassName = ChildClass; wndclass.hIcon = NULL; RegisterClass(&wndclass); hwnd = CreateWindow( TEXT("Hi"), TEXT("Treffer"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nShowCmd); UpdateWindow(hwnd); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hwndChild[DIVISIONS][DIVISIONS]; static int cxBlock, cyBlock; int x, y; switch(message) { case WM_CREATE: for(x=0; x<DIVISIONS; ++x) { for(y=0; y<DIVISIONS; ++y) { hwndChild[x][y] = CreateWindow(ChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) (y << 8 | x), (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); } } return 0; case WM_SIZE: cxBlock = LOWORD(lParam)/DIVISIONS; cyBlock = HIWORD(lParam)/DIVISIONS; for(x=0; x<DIVISIONS; ++x) { for(y=0; y<DIVISIONS; ++y) { MoveWindow(hwndChild[x][y], cxBlock * x, cyBlock * y, cxBlock, cyBlock, true); } } return 0; case WM_LBUTTONDOWN: MessageBeep(0); case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; static bool kreuz; switch(message) { case WM_CREATE: kreuz = false; return 0; case WM_LBUTTONDOWN: if(kreuz == false) { kreuz = true; InvalidateRect(hwnd, NULL, FALSE); } else { kreuz = false; InvalidateRect(hwnd, NULL, FALSE); } return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); Rectangle(hdc, 0, 0, rect.right, rect.bottom); if(kreuz == true) { MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, rect.right, rect.bottom); MoveToEx(hdc, rect.right, 0, NULL); LineTo(hdc, 0, rect.bottom); } EndPaint(hwnd, &ps); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
-
Alle deine Child-Windows habe eine gemeinsame WndProc und damit nutzen alle die boll Variable gemeinsam! Mit GetWindowLong / SetWindowLong lässt sich das auf jeden Fall mal lösen.
PS: Dein Umgang mit der bool-Variablen erscheint mir etwas umständlich