Rudy Opublikowano 3 Lipca 2010 Udostępnij Opublikowano 3 Lipca 2010 Witam! Mam pewien problem w WinAPI. Chciałbym, żeby po kliknięciu na button (kontrolkę) została ona wciśnięta. Przeszukałem MSDN i znalazłem parę funkcji, ogólnie mój kod operujący kontrolkami wygląda tak: __________________________________________________ // --= Plik nagłówkowy =-- enum GAMESTATE { Stop = 7, Play = 8, Pause = 9, Frame = 10 }; // --= Plik z funkcjami =-- #define WINDOWS_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> #include "header.h" GAMESTATE state = Stop; HWND ctrl [11]; // tablica z uchwytami kontrolek (te buttony to przedział 7-10) HICON img_butt [4]; // tablica z obrazkami LRESULT CALLBACK MainWinProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { HINSTANCE hInst = GetModuleHandle (NULL); // wczytywanie obrazków img_butt[0] = (HICON) LoadImage (hInst, "resources\\butt_rev.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); img_butt[1] = (HICON) LoadImage (hInst, "resources\\butt_play.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); img_butt[2] = (HICON) LoadImage (hInst, "resources\\butt_pause.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); img_butt[3] = (HICON) LoadImage (hInst, "resources\\butt_frame.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); // tworzenie kontrolek ctrl[ 7] = CreateWindowEx (NULL, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 10, 450, 22, 22, hwnd, NULL, hInst, NULL); ctrl[ 8] = CreateWindowEx (NULL, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 49, 450, 22, 22, hwnd, NULL, hInst, NULL); ctrl[ 9] = CreateWindowEx (NULL, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 88, 450, 22, 22, hwnd, NULL, hInst, NULL); ctrl[10] = CreateWindowEx (NULL, "BUTTON", NULL, WS_CHILD | WS_VISIBLE | BS_ICON, 127, 450, 22, 22, hwnd, NULL, hInst, NULL); // ustawianie właściwości (pokrywa sie z funkcjami wykonywanymi przy wciśnięciu ctrl[7]) Button_SetState (ctrl[ 7], TRUE); Button_Enable (ctrl[ 9], FALSE); // dodanie obrazków do przycisków SendMessage (ctrl[ 7], BM_SETIMAGE, IMAGE_ICON, (LPARAM)img_butt[0]); SendMessage (ctrl[ 8], BM_SETIMAGE, IMAGE_ICON, (LPARAM)img_butt[1]); SendMessage (ctrl[ 9], BM_SETIMAGE, IMAGE_ICON, (LPARAM)img_butt[2]); SendMessage (ctrl[10], BM_SETIMAGE, IMAGE_ICON, (LPARAM)img_butt[3]); } case WM_COMMAND: { // --= podział na poszczególne kontrolki (switch nie chce współpracować z wartościami w tablicy) int i = -1; for (int _i = 0; _i < 11; ++_i) if ((HWND)lParam == ctrl[_i]) i = _i; // przyciski if (i >= 7 && i < 11) switch (HIWORD(wParam)) { case BN_CLICKED: if (state != Frame) Button_SetState (ctrl[state], FALSE); state = static_cast<GAMESTATE> (i); Button_Enable (ctrl[ 9], i!=7); Button_Enable (ctrl[10], i!=8); if (state != Frame) Button_SetState (ctrl[state], TRUE); // MessageBox (NULL, "ClicK!!!", tostr(i), NULL); if (state == Frame) SendMessage (ctrl[9], BM_CLICK, 0, 0); break; } } break; case WM_DESTROY: // usuwanie ikonek DestroyIcon (img_butt[0]); DestroyIcon (img_butt[1]); DestroyIcon (img_butt[2]); DestroyIcon (img_butt[3]); PostQuitMessage (0); break; default: return DefWindowProc (hwnd, msg, wParam, lParam); } return 0; } __________________________________________________ Button_Set_State ustawia wciśnięcie przycisku. Button_Enable ustawia aktywność (można kliknąć, lub nie, coś jak przycisk zatrzymania w przeglądarce po wczytaniu strony). ctrl[7] to przycisk "Stop". Dezaktywuje tylko przycisk "Pause". ctrl[8] to przycisk "Play". Dezaktywuje tylko przycisk "Frame". ctrl[9] to przycisk "Pause". Aktywuje wszystkie przyciski. ctrl[10] to tzw. przycisk "Frame" (przesunięcie o jedną klatkę). Jako jedyny nie ma pozostać wciśnięty po kliknięciu. Po użyciu wywołuje przycisk "Pause" (ta funkcja później powędruje gdzie indziej). No to teraz opiszę problem :) . Teoretycznie wszystko powinno działać, ale jest parę niedociągnięć: - Gdy wciśniemy LPM wciśnięty button, odjedziemy myszką i puścimy LPM, button staje się zwykłym, niewciśniętym przyciskiem. - Wciśnięcie przycisku "Frame" symuluje wciśnięcie Pause, mimo to Pause nie pozostaje wciśnięte. - Każde wciśnięcie przycisku (poza Frame) wywołuje jego wciśnięcie dwukrotnie. Winowajcą jest tutaj Button_Set_State (... TRUE). gdy zmienia on wartość z FALSE na TRUE symuluje ponowne wciśnięcie przycisku (nie wiadomo czemu). Ma ktoś pomysł jak zaradzić tym problemom? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 3 Lipca 2010 Udostępnij Opublikowano 3 Lipca 2010 WinAPI + Cpp to masochizm. Polecam wxWidgets lub język C#, który jest wprost stworzony do takich wyczynów. Ale jak Ci zależy to: 1. Tak raczej powinno być... Sprawdź sobie inne aplikacje. 2. Poczytaj o GDI, czyści-rysuje ten region clienta, który jest tego wart. 3. To akurat twój błąd, a nie WinAPI. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rudy Opublikowano 3 Lipca 2010 Autor Udostępnij Opublikowano 3 Lipca 2010 Zostanę jednak przy C++. Uczę się WinAPI, bo podobno podstawy są wymagane do Direct. A poza tym lubię aplikacje okienkowe :sp_ike: No tak, raczej powinny "odskakiwać". Myślałem, żeby zrobić w ten sposób bo mniej miejsca zajmuje w przestrzeni roboczej, no ale skoro nie ma takiej możliwości, zrobię to inaczej. Pozostałe dwa problemy były zależne od pierwszego, skoro zmieniam sposób, problemy same znikną. Dzięki za pomoc, zamykam. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi