multim Temat założony przez niniejszego użytkownika |
[WinAPI] Ignorowanie komunikatu WM_LBUTTONDOWN / UP » 2017-11-14 20:39:20 Próbuję zrobić prosty program umożliwiający narysowanie prostokąta, koła lub trójkąta po kliknięciu myszy, przejechaniu do kolejnej współrzędnej i puszczeniu przycisku. Pomimo klikania odpowiedniego przycisku program ignoruje ten case i nie wywołuje funkcji rysowania. Błąd leży prawdopodobnie w WndProc(), ale nie potrafię go odnaleźć. Kod całego programu: #include <windows.h> #include <wchar.h>
LPCWSTR ClassName = TEXT( "Aplikacja testowa" );
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); void CreatePBs( HDC & hdc, HBRUSH * brush, HPEN * pen ); void DrawMenu( HWND hwnd, HDC & hdc, HBRUSH * brush, HPEN * pen, RECT & cr ); void Draw( HWND hwnd, int shape, BOOL transparent, HBRUSH * brush, HPEN * pen, int color, POINT & start, POINT & end ); int ChooseShape( POINT & cursor, int shape, RECT & cr ); int PickColor( POINT & cursor, int color, RECT & cr );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MSG Komunikat; WNDCLASSEX wc = { sizeof( WNDCLASSEX ), CS_VREDRAW | CS_HREDRAW, WndProc, 0, 0, hInstance, 0, LoadCursor( NULL, IDC_ARROW ), ( HBRUSH )( COLOR_WINDOW + 0 ), NULL, ClassName, 0 }; if( !RegisterClassEx( & wc ) ) { MessageBox( NULL, TEXT( "Błąd rejestracji tego okna!" ), TEXT( "Problem..." ), MB_ICONEXCLAMATION | MB_OK ); return 1; } HWND hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, ClassName, TEXT( "Aplikacja testowa" ), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 490, NULL, NULL, hInstance, 0 ); if( hwnd == NULL ) { MessageBox( NULL, TEXT( "Błąd utworzenia okna." ), TEXT( "Problem..." ), MB_ICONEXCLAMATION ); UnregisterClass( ClassName, hInstance ); return 1; } ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); while( GetMessage( & Komunikat, NULL, 0, 0 ) ) { TranslateMessage( & Komunikat ); DispatchMessage( & Komunikat ); } UnregisterClass( ClassName, hInstance ); return Komunikat.wParam; }
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hdc; RECT cr; HBRUSH brush[ 16 ]; HPEN pen[ 16 ]; int state = 0, shape, color; BOOL lBtnDwn = false, transparent = true; POINT start, end; switch( msg ) { case WM_CLOSE: DestroyWindow( hwnd ); return 0; case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_PAINT: { hdc = BeginPaint( hwnd, & ps ); CreatePBs( hdc, brush, pen ); DrawMenu( hwnd, hdc, brush, pen, cr ); EndPaint( hwnd, & ps ); break; } case WM_GETMINMAXINFO: { LPMINMAXINFO lpMMI =( LPMINMAXINFO ) lParam; lpMMI->ptMinTrackSize.x = 300; lpMMI->ptMinTrackSize.y = 490; break; } case WM_MOUSEMOVE: { POINT cursor; GetCursorPos( & cursor ); ScreenToClient( hwnd, & cursor ); GetClientRect( hwnd, & cr ); TCHAR buff[ 40 ]; if(( cursor.x < cr.right - 100 ) &&( cursor.y < cr.bottom ) ) state = 1; else if(( cursor.x >= cr.right - 85 ) &&( cursor.y < 325 ) ) state = 2; else if(( cursor.y > 360 ) &&( cursor.y < 425 ) ) state = 3; swprintf_s( buff, 40, TEXT( "Paint (x: %d, y: %d), state: %d" ), cursor.x, cursor.y, state ); SetWindowText( hwnd, buff ); break; } case WM_LBUTTONDOWN: { POINT cursor; GetCursorPos( & cursor ); ScreenToClient( hwnd, & cursor ); if( state == 2 ) { color = PickColor( cursor, color, cr ); transparent = false; } if( state == 3 ) shape = ChooseShape( cursor, shape, cr ); if( !lBtnDwn && state == 1 ) { lBtnDwn = true; GetCursorPos( & start ); ScreenToClient( hwnd, & start ); } break; } case WM_LBUTTONUP: { HDC hdc = GetDC( hwnd ); CreatePBs( hdc, brush, pen ); GetCursorPos( & end ); ScreenToClient( hwnd, & end ); if( state == 1 ) Draw( hwnd, shape, transparent, brush, pen, color, start, end ); ReleaseDC( hwnd, hdc ); lBtnDwn = false; break; } default: return DefWindowProc( hwnd, msg, wParam, lParam ); } return 0; }
void CreatePBs( HDC & hdc, HBRUSH * brush, HPEN * pen ) { COLORREF color[ 16 ] = { 0x000000, 0x777777, 0x000080, 0x0000FF, 0x004000, 0x00FF00, 0x008080, 0x00FFFF, 0x800000, 0xFF0000, 0x800040, 0xFF00FF, 0x808040, 0xFFFF00, 0x806060, 0xFFFFFF }; for( int i = 0; i < 16; i++ ) { brush[ i ] = CreateSolidBrush( color[ i ] ); pen[ i ] = CreatePen( PS_SOLID, 1, color[ i ] ); } }
void DrawMenu( HWND hwnd, HDC & hdc, HBRUSH * brush, HPEN * pen, RECT & cr ) { enum colors { black, gray, darkred, red, darkgreen, green, darkyellow, yellow, darkblue, blue, purple, pink, seal, lightblue, darkgray, white }; HBRUSH bkMenu = CreateSolidBrush( 0xC0C0C0 ); HBRUSH OldBrush =( HBRUSH ) SelectObject( hdc, brush[ white ] ); HPEN OldPen =( HPEN ) SelectObject( hdc, pen[ black ] ); GetClientRect( hwnd, & cr ); Rectangle( hdc, cr.left, cr.top, cr.right, cr.bottom ); SelectObject( hdc, bkMenu ); SelectObject( hdc, pen[ blue ] ); Rectangle( hdc, cr.right - 100, 1, cr.right - 1, cr.bottom - 1 ); for( int i = 0; i < 16; i++ ) { SelectObject( hdc, pen[ i ] ); SelectObject( hdc, brush[ i++ ] ); Rectangle( hdc, cr.right - 85, 20 * i + 25, cr.right - 60, 20 * i + cr.top ); SelectObject( hdc, pen[ i ] ); SelectObject( hdc, brush[ i ] ); Rectangle( hdc, cr.right - 40, 20 * i + 25, cr.right - 15, 20 * i + cr.top ); } SelectObject( hdc, pen[ black ] ); for( int i = 0; i < 2; i++ ) { Rectangle( hdc, cr.right - 85, 40 * i + 360, cr.right - 60, 40 * i + 385 ); Rectangle( hdc, cr.right - 40, 40 * i + 360, cr.right - 15, 40 * i + 385 ); } POINT triangle[ 3 ] = { { cr.right - 35, 365 }, { cr.right - 20, 365 }, { cr.right - 28, 380 } }; Polygon( hdc, triangle, 3 ); for( int i = 0; i < 3; i++ ) { triangle[ i ].y += 40; } SelectObject( hdc, brush[ black ] ); Polygon( hdc, triangle, 3 ); Rectangle( hdc, cr.right - 80, 365, cr.right - 65, 380 ); Ellipse( hdc, cr.right - 80, 405, cr.right - 65, 420 ); for( int i = 0; i < 16; i++ ) { DeleteObject( brush[ i ] ); DeleteObject( pen[ i ] ); } DeleteObject( bkMenu ); }
void Draw( HWND hwnd, int shape, BOOL transparent, HBRUSH * brush, HPEN * pen, int color, POINT & start, POINT & end ) { HDC hdc = GetDC( hwnd ); if( !transparent ) { SelectObject( hdc, brush[ color ] ); SelectObject( hdc, pen[ color ] ); } else { SelectObject( hdc, GetStockObject( NULL_BRUSH ) ); SelectObject( hdc, pen[ color ] ); } switch( shape ) { case 1: { Rectangle( hdc, start.x, start.y, end.x, end.y ); } break; case 2: { Ellipse( hdc, start.x, start.y, end.x, end.y ); } break; case 3: { SelectObject( hdc, GetStockObject( NULL_BRUSH ) ); POINT point[ 3 ] = { { start.x, start.y }, { end.x, end.y }, { end.x, start.y } }; Polygon( hdc, point, 3 ); } break; case 4: { POINT point[ 3 ] = { { start.x, start.y }, { end.x, end.y }, { end.x, start.y } }; Polygon( hdc, point, 3 ); } break; default: return; } ReleaseDC( hwnd, hdc ); }
int ChooseShape( POINT & cursor, int shape, RECT & cr ) { int Shape = shape; if(( cursor.x >=( cr.right - 85 ) ) &&( cursor.x <=( cr.right - 60 ) ) &&( cursor.y >= 395 ) &&( cursor.y <= 420 ) ) Shape = 1; else if(( cursor.x >=( cr.right - 85 ) ) &&( cursor.x <=( cr.right - 60 ) ) &&( cursor.y >= 435 ) &&( cursor.y <= 460 ) ) Shape = 2; else if(( cursor.x >=( cr.right - 40 ) ) &&( cursor.x <=( cr.right - 15 ) ) &&( cursor.y >= 395 ) &&( cursor.y <= 420 ) ) Shape = 3; else if(( cursor.x >=( cr.right - 40 ) ) &&( cursor.x <=( cr.right - 15 ) ) &&( cursor.y >= 435 ) &&( cursor.y <= 460 ) ) Shape = 4; return Shape; }
int PickColor( POINT & cursor, int color, RECT & cr ) { enum colors { black, gray, darkred, red, darkgreen, green, darkyellow, yellow, darkblue, blue, purple, pink, seal, lightblue, darkgray, white }; int Color = color; for( int i = 0; i < 16; i++ ) { if(( cursor.x >=( cr.right - 85 ) ) &&( cursor.x <=( cr.right - 60 ) ) &&( cursor.y >=( 20 * i + 25 ) ) &&( cursor.y <=( 20 * i + cr.top ) ) ) Color = i++; if(( cursor.x >=( cr.right - 40 ) ) &&( cursor.x <=( cr.right - 15 ) ) &&( cursor.y >=( 20 * i + 25 ) ) &&( cursor.y <=( 20 * i + cr.top ) ) ) Color = i; } return Color; }
|