Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

WINAPI wyświtlanie linii w oknie aplikacji

Ostatnio zmodyfikowano 2021-03-19 16:27
Autor Wiadomość
Temat założony przez niniejszego użytkownika
WINAPI wyświtlanie linii w oknie aplikacji
» 2021-03-19 15:23:41
Witam, tworzę prostą gierkę "kółko - krzyżyk" i problem pojawia się podczas zakreślania zwycięskich znaków na planszy.
Na razie dotyczy to pierwszego rzędu na planszy. Po utworzeniu 3-ch kółek lub krzyżyków zamiarem moim jest przerysowanie przez ten rząd niebieskiej linii. I nawet się to dzieje z jedna przypadłością - nie wyświetla się ta linia na ostatnio klikniętym polu w tym rzędzie tzn. na 3-cim kółku czy krzyżyku. Jeżeli kliknę potem na innym wolnym polu na planszy to linia się pojawia.
Nie wiem jak to poprawić . Próbowałem przez UpdateWindow ale nie działa. Cały kod programu poniżej.

C/C++
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define B_L1P1 501  
// przypisanie kazdemu BUTTON kodu liczbowego
#define B_L1P2 502
#define B_L1P3 503
#define B_L2P1 504
#define B_L2P2 505
#define B_L2P3 506
#define B_L3P1 507
#define B_L3P2 508
#define B_L3P3 509

using namespace std;

LPCTSTR NazwaKlasy = TEXT( "Okno Aplikacji" );
MSG Komunikat; // przechowanie komunikatow
HWND h_glowneokno; // uchwyt na glowne okno programu
HWND hL1P1, hL1P2, hL1P3, hL2P1, hL2P2, hL2P3, hL3P1, hL3P2, hL3P3; // uchwyty do przyciskow
BYTE znak = 0; // zmienna przechowujaca info czy kolko czy krzyzyk ma byc kolejne
UINT uPlansza[ 3 ][ 3 ] = {( 0, 0, 0 ),( 0, 0, 0 ),( 0, 0, 0 ) }; // tab. do zapisu planszy - 0 wart.poczatkowa, 2 - to X, 4 - to O

LRESULT CALLBACK ObslugaZdarzen( HWND hwind, UINT umsg, WPARAM wParam, LPARAM lParam ); // naglowek funkcji obslugujacej zdarzenia
VOID StanRozgrywki( UINT uPlansza[ 3 ][ 3 ] ); // f. sprawdzajaca czy ktos wygral
VOID Rysuj(); //  f.rysujaca linie na wygranym rzedzie

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
   
   
// okno wypełnione kafelkami bitmapy
    // HBITMAP hBitmapa;
    // HBRUSH hPedzelOkna;
   
    // tworzymy pędzel wypełnienia okna
    //  hBitmapa = (HBITMAP)LoadImage(NULL, TEXT("D:\\Kostki.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    //  hPedzelOkna = CreatePatternBrush(hBitmapa);
   
   
WNDCLASSEX wc; // zdefiniowanie struktury okna glownego programu
   
wc.cbSize = sizeof( WNDCLASSEX );
   
wc.style = 0;
   
wc.lpfnWndProc = ObslugaZdarzen;
   
wc.cbClsExtra = 0;
   
wc.cbWndExtra = 0;
   
wc.hInstance = hInstance;
   
wc.hIcon = LoadIcon( NULL, IDI_SHIELD );
   
wc.hCursor = LoadCursor( NULL, IDC_SIZEALL );
   
wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 ); //hPedzelOkna;
   
wc.lpszMenuName = NULL;
   
wc.lpszClassName = NazwaKlasy;
   
wc.hIconSm = LoadIcon( NULL, IDI_SHIELD );
   
   
if( !RegisterClassEx( & wc ) ) // rejestracja okna w systemie
   
{
       
MessageBox( NULL, TEXT( "Błąd rejestracji okna.!" ), TEXT( "Błąd krytyczny !" ), MB_ICONEXCLAMATION | MB_OK );
       
return 1;
   
}
   
   
h_glowneokno = CreateWindowEx( WS_EX_CLIENTEDGE, NazwaKlasy, TEXT( "Gra kółko -- krzyżyk" ), WS_OVERLAPPEDWINDOW,
   
( GetSystemMetrics( SM_CXSCREEN ) - 502 ) / 2,( GetSystemMetrics( SM_CYSCREEN ) - 600 ) / 2, 502, 600, NULL, NULL, hInstance, NULL ); // utworzenie okna glownego
   
if( h_glowneokno == NULL )
   
{
       
MessageBox( NULL, TEXT( "Błąd kreacji okna programu" ), TEXT( "Blad krytyczny !" ), MB_ICONEXCLAMATION );
       
return 1;
   
}
   
   
HFONT hNormalFont = CreateFont( 72, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
   
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT( "Arial" ) ); //  stworzenie czcionki do BUTTON
   
    //  tworzenie przyciskow
   
hL1P1 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 100, 100, 100, 100, h_glowneokno,( HMENU ) B_L1P1, hInstance, NULL );
   
SendMessage( hL1P1, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL1P2 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 201, 100, 100, 100, h_glowneokno,( HMENU ) B_L1P2, hInstance, NULL );
   
SendMessage( hL1P2, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL1P3 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 302, 100, 100, 100, h_glowneokno,( HMENU ) B_L1P3, hInstance, NULL );
   
SendMessage( hL1P3, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL2P1 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 100, 201, 100, 100, h_glowneokno,( HMENU ) B_L2P1, hInstance, NULL );
   
SendMessage( hL2P1, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL2P2 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 201, 201, 100, 100, h_glowneokno,( HMENU ) B_L2P2, hInstance, NULL );
   
SendMessage( hL2P2, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL2P3 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 302, 201, 100, 100, h_glowneokno,( HMENU ) B_L2P3, hInstance, NULL );
   
SendMessage( hL2P3, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL3P1 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 100, 302, 100, 100, h_glowneokno,( HMENU ) B_L3P1, hInstance, NULL );
   
SendMessage( hL3P1, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL3P2 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 201, 302, 100, 100, h_glowneokno,( HMENU ) B_L3P2, hInstance, NULL );
   
SendMessage( hL3P2, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
hL3P3 = CreateWindowEx( 0, TEXT( "BUTTON" ), NULL, WS_CHILD | WS_VISIBLE, 302, 302, 100, 100, h_glowneokno,( HMENU ) B_L3P3, hInstance, NULL );
   
SendMessage( hL3P3, WM_SETFONT,( WPARAM ) hNormalFont, 0 );
   
   
ShowWindow( h_glowneokno, SW_SHOW ); // wyswietl okno glowne
   
UpdateWindow( h_glowneokno ); // odswiez okno glowne
   
   
while( GetMessage( & Komunikat, NULL, 0, 0 ) ) // petla przechwytujaca komunikaty z systemu
   
{
       
TranslateMessage( & Komunikat );
       
DispatchMessage( & Komunikat );
   
}
   
return static_cast < INT >( Komunikat.wParam );
}

LRESULT CALLBACK ObslugaZdarzen( HWND h_glowneokno, UINT umsg, WPARAM wParam, LPARAM lParam ) // funkcja obslugi zdarzen
{
   
switch( umsg )
   
{
   
case WM_CLOSE: // nacisniecie x w oknie programu
       
DestroyWindow( h_glowneokno );
       
break;
   
case WM_DESTROY:
       
PostQuitMessage( 0 );
       
break;
   
case WM_COMMAND:
       
switch( wParam )
       
{
       
case B_L1P1:
           
if( znak == 0 )
           
{
               
SetWindowText( hL1P1, TEXT( "X" ) );
               
uPlansza[ 0 ][ 0 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL1P1, TEXT( "O" ) );
               
uPlansza[ 0 ][ 0 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL1P1, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L1P2:
           
if( znak == 0 )
           
{
               
SetWindowText( hL1P2, TEXT( "X" ) );
               
uPlansza[ 0 ][ 1 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL1P2, TEXT( "O" ) );
               
uPlansza[ 0 ][ 1 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL1P2, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L1P3:
           
if( znak == 0 )
           
{
               
SetWindowText( hL1P3, TEXT( "X" ) );
               
uPlansza[ 0 ][ 2 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL1P3, TEXT( "O" ) );
               
uPlansza[ 0 ][ 2 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL1P3, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L2P1:
           
if( znak == 0 )
           
{
               
SetWindowText( hL2P1, TEXT( "X" ) );
               
uPlansza[ 1 ][ 0 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL2P1, TEXT( "O" ) );
               
uPlansza[ 1 ][ 0 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL2P1, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L2P2:
           
if( znak == 0 )
           
{
               
SetWindowText( hL2P2, TEXT( "X" ) );
               
uPlansza[ 1 ][ 1 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL2P2, TEXT( "O" ) );
               
uPlansza[ 1 ][ 1 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL2P2, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L2P3:
           
if( znak == 0 )
           
{
               
SetWindowText( hL2P3, TEXT( "X" ) );
               
uPlansza[ 1 ][ 2 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL2P3, TEXT( "O" ) );
               
uPlansza[ 1 ][ 2 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL2P3, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L3P1:
           
if( znak == 0 )
           
{
               
SetWindowText( hL3P1, TEXT( "X" ) );
               
uPlansza[ 2 ][ 0 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL3P1, TEXT( "O" ) );
               
uPlansza[ 2 ][ 0 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL3P1, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L3P2:
           
if( znak == 0 )
           
{
               
SetWindowText( hL3P2, TEXT( "X" ) );
               
uPlansza[ 2 ][ 1 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL3P2, TEXT( "O" ) );
               
uPlansza[ 2 ][ 1 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL3P2, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
case B_L3P3:
           
if( znak == 0 )
           
{
               
SetWindowText( hL3P3, TEXT( "X" ) );
               
uPlansza[ 2 ][ 2 ] = 2;
               
znak = 1;
           
}
           
else
           
{
               
SetWindowText( hL3P3, TEXT( "O" ) );
               
uPlansza[ 2 ][ 2 ] = 4;
               
znak = 0;
           
}
           
EnableWindow( hL3P3, FALSE );
           
StanRozgrywki( uPlansza );
           
break;
       
}
       
default:
       
return DefWindowProc( h_glowneokno, umsg, wParam, lParam );
       
break;
   
}
   
   
return 0;
}

VOID StanRozgrywki( UINT uPlansza[ ][ 3 ] )
{
   
if( uPlansza[ 0 ][ 0 ] == 2 and uPlansza[ 0 ][ 1 ] == 2 and uPlansza[ 0 ][ 2 ] == 2 ) //pierwsza pozioma dla X
       
 Rysuj();
   
   
if( uPlansza[ 1 ][ 0 ] == 2 and uPlansza[ 1 ][ 1 ] == 2 and uPlansza[ 1 ][ 2 ] == 2 ) //druga pozioma dla X
       
 MessageBox( h_glowneokno, TEXT( "druga pozioma" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 2 ][ 0 ] == 2 and uPlansza[ 2 ][ 1 ] == 2 and uPlansza[ 2 ][ 2 ] == 2 ) //trzecia pozioma dla X
       
 MessageBox( h_glowneokno, TEXT( "trzecia pozioma" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 0 ] == 2 and uPlansza[ 1 ][ 0 ] == 2 and uPlansza[ 2 ][ 0 ] == 2 ) //pierwsza pionowa dla X
       
 MessageBox( h_glowneokno, TEXT( "pierwsza pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 1 ] == 2 and uPlansza[ 1 ][ 1 ] == 2 and uPlansza[ 2 ][ 1 ] == 2 ) //druga pionowa dla X
       
 MessageBox( h_glowneokno, TEXT( "druga pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 2 ] == 2 and uPlansza[ 1 ][ 2 ] == 2 and uPlansza[ 2 ][ 2 ] == 2 ) //trzecia pionowa dla X
       
 MessageBox( h_glowneokno, TEXT( "trzecia pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 0 ] == 2 and uPlansza[ 1 ][ 1 ] == 2 and uPlansza[ 2 ][ 2 ] == 2 ) //prawy skos dla X
       
 MessageBox( h_glowneokno, TEXT( "prawy skos" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 2 ] == 2 and uPlansza[ 1 ][ 1 ] == 2 and uPlansza[ 2 ][ 0 ] == 2 ) //lewy skos dla X
       
 MessageBox( h_glowneokno, TEXT( "lewy skos" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 0 ] == 4 and uPlansza[ 0 ][ 1 ] == 4 and uPlansza[ 0 ][ 2 ] == 4 ) //pierwsza pozioma dla O
       
 MessageBox( h_glowneokno, TEXT( "pierwsza pozioma" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 1 ][ 0 ] == 4 and uPlansza[ 1 ][ 1 ] == 4 and uPlansza[ 1 ][ 2 ] == 4 ) //druga pozioma dla O
       
 MessageBox( h_glowneokno, TEXT( "druga pozioma" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 2 ][ 0 ] == 4 and uPlansza[ 2 ][ 1 ] == 4 and uPlansza[ 2 ][ 2 ] == 4 ) //trzecia pozioma dla O
       
 MessageBox( h_glowneokno, TEXT( "trzecia pozioma" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 0 ] == 4 and uPlansza[ 1 ][ 0 ] == 4 and uPlansza[ 2 ][ 0 ] == 4 ) //pierwsza pionowa dla O
       
 MessageBox( h_glowneokno, TEXT( "pierwsza pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 1 ] == 4 and uPlansza[ 1 ][ 1 ] == 4 and uPlansza[ 2 ][ 1 ] == 4 ) //druga pionowa dla O
       
 MessageBox( h_glowneokno, TEXT( "druga pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 2 ] == 4 and uPlansza[ 1 ][ 2 ] == 4 and uPlansza[ 2 ][ 2 ] == 4 ) //trzecia pionowa dla O
       
 MessageBox( h_glowneokno, TEXT( "trzecia pionowa" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 0 ] == 4 and uPlansza[ 1 ][ 1 ] == 4 and uPlansza[ 2 ][ 2 ] == 4 ) //prawy skos dla O
       
 MessageBox( h_glowneokno, TEXT( "prawy skos" ), TEXT( "Test" ), MB_OK );
   
   
if( uPlansza[ 0 ][ 2 ] == 4 and uPlansza[ 1 ][ 1 ] == 4 and uPlansza[ 2 ][ 0 ] == 4 ) //lewy skos dla O
       
 MessageBox( h_glowneokno, TEXT( "lewy skos" ), TEXT( "Test" ), MB_OK );
   
}

VOID Rysuj()
{
   
HDC hdcObszarKlienta = GetDC( h_glowneokno );
   
SaveDC( hdcObszarKlienta );
   
HPEN hpenPioro = CreatePen( PS_SOLID, 5, RGB( 0, 0, 255 ) );
   
SelectObject( hdcObszarKlienta, hpenPioro );
   
   
POINT ptPoprzedniaPozycja;
   
MoveToEx( hdcObszarKlienta, 90, 150, & ptPoprzedniaPozycja );
   
LineTo( hdcObszarKlienta, 410, 150 );
   
   
RestoreDC( hdcObszarKlienta, - 1 );
   
DeleteDC( hdcObszarKlienta );
   
DeleteObject( hpenPioro );
}
P-178313
» 2021-03-19 16:27:32
Zrób tak: utwórz sobie specjalną kontrolkę na potrzeby rysowania tej linii
C/C++
HWND hOverlay; // globalnie

// ..
RECT clientRect;
GetClientRect( h_glowneokno, & clientRect );
hOverlay = CreateWindowEx( 0, TEXT( "STATIC" ), NULL, WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 0, 0, clientRect.right, clientRect.bottom, h_glowneokno, NULL, hInstance, NULL );
Utwórz ją na koniec, by się rysowała jako ostatnia. Flaga SS_OWNERDRAW sprawi że jesteś odpowiedzialny za jej rysowanie, więc potrzeba wtedy napisać obsługę dla komunikatu wysyłanego w celu narysowania kontrolki:
C/C++
case WM_DRAWITEM:
{
   
LPDRAWITEMSTRUCT lpdis =( LPDRAWITEMSTRUCT ) lParam;
   
   
if( lpdis->hwndItem == hOverlay )
   
{
       
if( uPlansza[ 0 ][ 0 ] == 2 and uPlansza[ 0 ][ 1 ] == 2 and uPlansza[ 0 ][ 2 ] == 2 )
       
{
           
HPEN hpenPioro = CreatePen( PS_SOLID, 5, RGB( 0, 0, 255 ) );
           
SelectObject( lpdis->hDC, hpenPioro );
           
           
POINT ptPoprzedniaPozycja;
           
MoveToEx( lpdis->hDC, 90, 150, & ptPoprzedniaPozycja );
           
LineTo( lpdis->hDC, 410, 150 );
           
           
DeleteObject( hpenPioro );
       
}
    }
   
   
return TRUE;
}
Dorzuć do aktualizacji stanu gry wywołanie InvalidateRect() żeby wymusić narysowanie kontrolek od nowa:
C/C++
InvalidateRect( h_glowneokno, NULL, FALSE );
P-178315
« 1 »
  Strona 1 z 1