XONX Temat założony przez niniejszego użytkownika |
[WinAPI] Scrollbar wraz z kontrolką Static » 2013-06-02 11:10:57 No to tak. Problem jest taki. Mam aplikację okienkową w WinApi. Wszystko pięknie i w ogóle, ale kiedy próbuję dodać scrollbara do okienka potomnego typu static, to scrollbar zwyczajnie się nie przesuwa. Kiedy pozmieniam w całym kodzie związanym ze scrollbarem nazwę mojego okienka static na nazwę mojego głównego okienka, wszystko jest ok, przesuwa się normalnie. Tylko że ja chcę, żeby przesuwał mi się static, a nie całe okno. Mam nadzieję, że zbytnio nie namieszałem i liczę na pomoc :) |
|
xevuel |
» 2013-06-02 11:22:19 Pokaż kod. W jaki sposób tworzysz scrollbara? Poprzez style WS_*SCROLL, subclassing, czy osobną kontrolkę? |
|
XONX Temat założony przez niniejszego użytkownika |
» 2013-06-02 11:29:20 #include <windows.h> #define ID_PRZYCISK1 501 #define ID_PRZYCISK2 502 #define ID_PRZYCISK3 503
LPSTR NazwaKlasy = "Klasa Okienka"; MSG Komunikat; HWND hPrzycisk1; HWND hPrzycisk2; HWND hPrzycisk3; HWND hStatic;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { WNDCLASSEX wc; wc.cbSize = sizeof( WNDCLASSEX ); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 ); wc.lpszMenuName = NULL; wc.lpszClassName = NazwaKlasy; wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); if( !RegisterClassEx( & wc ) ) return 1; HWND hwnd; hwnd = CreateWindowEx( WS_EX_WINDOWEDGE, NazwaKlasy, "okno", WS_BORDER | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL ); hPrzycisk1 = CreateWindowEx( 0, "BUTTON", "1", WS_CHILD | WS_VISIBLE, 15, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK1, hInstance, NULL ); hPrzycisk2 = CreateWindowEx( 0, "BUTTON", "2", WS_CHILD | WS_VISIBLE, 300, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK2, hInstance, NULL ); hPrzycisk3 = CreateWindowEx( 0, "BUTTON", "3", WS_CHILD | WS_VISIBLE, 580, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK3, hInstance, NULL ); hStatic = CreateWindowEx( 0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_CENTER, 20, 20, 750, 400, hwnd, NULL, hInstance, NULL ); SetWindowText( hStatic, "" ); RECT okno; GetClientRect( hwnd, & okno ); SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = 0; si.nMax = 1000; si.nPage = okno.bottom; si.nPos = 0; SetScrollInfo( hwnd, SB_VERT, & si, TRUE ); int pozycja = si.nPos; int dy = -( pozycja - si.nPos ); ScrollWindowEx( hwnd, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, NULL ); UpdateWindow( hwnd ); ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); while( GetMessage( & Komunikat, NULL, 0, 0 ) ) { TranslateMessage( & Komunikat ); DispatchMessage( & Komunikat ); } return Komunikat.wParam; }
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_CLOSE: DestroyWindow( hwnd ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, msg, wParam, lParam ); break; case WM_VSCROLL: { SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS; GetScrollInfo( hwnd, SB_VERT, & si ); int pozycja = si.nPos; switch( LOWORD( wParam ) ) { case SB_TOP: pozycja = 0; break; case SB_BOTTOM: pozycja = 1000; break; case SB_LINEUP: if( pozycja > 0 ) { pozycja--; } break; case SB_LINEDOWN: if( pozycja < 1000 ) { pozycja++; } break; case SB_PAGEUP: pozycja -= si.nPage; if( pozycja < 0 ) { pozycja = 0; } break; case SB_PAGEDOWN: pozycja += si.nPage; if( pozycja > 1000 ) { pozycja = 1000; } break; case SB_THUMBPOSITION: pozycja = si.nTrackPos; break; case SB_THUMBTRACK: pozycja = si.nTrackPos; break; } int dy = -( pozycja - si.nPos ); ScrollWindowEx( hwnd, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE ); UpdateWindow( hwnd ); ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS; si.nPos = pozycja; SetScrollInfo( hwnd, SB_VERT, & si, TRUE ); } break; case WM_COMMAND: switch( wParam ) { case ID_PRZYCISK1: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK2: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK3: SetWindowText( hStatic, "" ); } break; } return 0; }
Teksty powycinałem, ale jeśli chodzi o te przyciski, to założenie było takie, że naciskasz je i tekst na polu static się zmienia (i to działa :D). Jakby ktoś powiedział jak zrobić tą ramkę dookoła kodu na forum to na pewno byłoby bardziej czytelne. PS: To jest ta wersja kodu, która przesuwa całe okno. //Edit: Program tworzyłem w oparciu o kurs w WinApi z tej strony, nie jestem pewien czy wszystko zrozumiałem. |
|
xevuel |
» 2013-06-02 11:34:44 PS: To jest ta wersja kodu, która przesuwa całe okno. |
Wszystko fajnie, tylko po co nam kod który działa? ;) Wklej ten błędny :) Jakby ktoś powiedział jak zrobić tą ramkę dookoła kodu na forum to na pewno byłoby bardziej czytelne. |
[cpp]...[/cpp] Więcej znaczników: Kurs STC |
|
XONX Temat założony przez niniejszego użytkownika |
» 2013-06-02 11:41:19 #include <windows.h> #define ID_PRZYCISK1 501 #define ID_PRZYCISK2 502 #define ID_PRZYCISK3 503
LPSTR NazwaKlasy = "Klasa Okienka"; MSG Komunikat; HWND hPrzycisk1; HWND hPrzycisk2; HWND hPrzycisk3; HWND hStatic;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { WNDCLASSEX wc; wc.cbSize = sizeof( WNDCLASSEX ); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 ); wc.lpszMenuName = NULL; wc.lpszClassName = NazwaKlasy; wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); if( !RegisterClassEx( & wc ) ) return 1; HWND hwnd; hwnd = CreateWindowEx( WS_EX_WINDOWEDGE, NazwaKlasy, "okno", WS_BORDER | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL ); hPrzycisk1 = CreateWindowEx( 0, "BUTTON", "1", WS_CHILD | WS_VISIBLE, 15, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK1, hInstance, NULL ); hPrzycisk2 = CreateWindowEx( 0, "BUTTON", "2", WS_CHILD | WS_VISIBLE, 300, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK2, hInstance, NULL ); hPrzycisk3 = CreateWindowEx( 0, "BUTTON", "3", WS_CHILD | WS_VISIBLE, 580, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK3, hInstance, NULL ); hStatic = CreateWindowEx( 0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | SS_CENTER, 20, 20, 750, 400, hwnd, NULL, hInstance, NULL ); SetWindowText( hStatic, "" ); RECT okno; GetClientRect( hStatic, & okno ); SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = 0; si.nMax = 1000; si.nPage = okno.bottom; si.nPos = 0; SetScrollInfo( hStatic, SB_VERT, & si, TRUE ); int pozycja = si.nPos; int dy = -( pozycja - si.nPos ); ScrollWindowEx( hStatic, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, NULL ); UpdateWindow( hStatic ); ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); while( GetMessage( & Komunikat, NULL, 0, 0 ) ) { TranslateMessage( & Komunikat ); DispatchMessage( & Komunikat ); } return Komunikat.wParam; }
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_CLOSE: DestroyWindow( hwnd ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, msg, wParam, lParam ); break; case WM_VSCROLL: { SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS; GetScrollInfo( hStatic, SB_VERT, & si ); int pozycja = si.nPos; switch( LOWORD( wParam ) ) { case SB_TOP: pozycja = 0; break; case SB_BOTTOM: pozycja = 1000; break; case SB_LINEUP: if( pozycja > 0 ) { pozycja--; } break; case SB_LINEDOWN: if( pozycja < 1000 ) { pozycja++; } break; case SB_PAGEUP: pozycja -= si.nPage; if( pozycja < 0 ) { pozycja = 0; } break; case SB_PAGEDOWN: pozycja += si.nPage; if( pozycja > 1000 ) { pozycja = 1000; } break; case SB_THUMBPOSITION: pozycja = si.nTrackPos; break; case SB_THUMBTRACK: pozycja = si.nTrackPos; break; } int dy = -( pozycja - si.nPos ); ScrollWindowEx( hStatic, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE ); UpdateWindow( hStatic ); ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS; si.nPos = pozycja; SetScrollInfo( hStatic, SB_VERT, & si, TRUE ); } break; case WM_COMMAND: switch( wParam ) { case ID_PRZYCISK1: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK2: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK3: SetWindowText( hStatic, "" ); } break; } return 0; }
|
|
xevuel |
» 2013-06-02 11:55:36 Kontrolka Static jest kontrolką, która w zasadzie praktycznie w ogóle nie reaguje na działania użytkownika. Także na pewno nie wyśle Ci komunikatu WM_VSCROLL do procedury okna (w zasadzie większość kontrolek rzadko kiedy wysyła komunikaty WM_* do głównej procedury). Rozwiązanie: Kod właściwie wydaje się być prawie dobrym :) Musisz tylko utworzyć osobną kontrolkę ( ScrollBar), która wyśle Ci ten komunikat, i pozmieniać uchwyty przekazywane do funkcji GetScrollInfo/SetScrollInfo na te prowadzące do scrollbara. Daj znać, czy Ci się udało ;) |
|
XONX Temat założony przez niniejszego użytkownika |
» 2013-06-02 12:09:05 Chyba coś źle zrobiłem, bo dalej nie działa :/ Z tego co zrozumiałem powinno być tak: #include <windows.h> #define ID_PRZYCISK1 501 #define ID_PRZYCISK2 502 #define ID_PRZYCISK3 503
LPSTR NazwaKlasy = "Klasa Okienka"; MSG Komunikat; HWND hPrzycisk1; HWND hPrzycisk2; HWND hPrzycisk3; HWND hStatic; HWND hScroll;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { WNDCLASSEX wc; wc.cbSize = sizeof( WNDCLASSEX ); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 ); wc.lpszMenuName = NULL; wc.lpszClassName = NazwaKlasy; wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); if( !RegisterClassEx( & wc ) ) return 1; HWND hwnd; hwnd = CreateWindowEx( WS_EX_WINDOWEDGE, NazwaKlasy, "okno", WS_BORDER | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL ); hPrzycisk1 = CreateWindowEx( 0, "BUTTON", "1", WS_CHILD | WS_VISIBLE, 15, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK1, hInstance, NULL ); hPrzycisk2 = CreateWindowEx( 0, "BUTTON", "2", WS_CHILD | WS_VISIBLE, 300, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK2, hInstance, NULL ); hPrzycisk3 = CreateWindowEx( 0, "BUTTON", "3", WS_CHILD | WS_VISIBLE, 580, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK3, hInstance, NULL ); hStatic = CreateWindowEx( 0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | SS_CENTER, 20, 20, 750, 400, hwnd, NULL, hInstance, NULL ); SetWindowText( hStatic, "" ); RECT okno; GetClientRect( hStatic, & okno ); SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = 0; si.nMax = 1000; si.nPage = okno.bottom; si.nPos = 0; SetScrollInfo( hScroll, SB_VERT, & si, TRUE ); int pozycja = si.nPos; int dy = -( pozycja - si.nPos ); ScrollWindowEx( hStatic, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, NULL ); UpdateWindow( hStatic ); ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); while( GetMessage( & Komunikat, NULL, 0, 0 ) ) { TranslateMessage( & Komunikat ); DispatchMessage( & Komunikat ); } return Komunikat.wParam; }
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_CLOSE: DestroyWindow( hwnd ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, msg, wParam, lParam ); break; case WM_VSCROLL: { SCROLLINFO si; ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS; GetScrollInfo( hScroll, SB_VERT, & si ); int pozycja = si.nPos; switch( LOWORD( wParam ) ) { case SB_TOP: pozycja = 0; break; case SB_BOTTOM: pozycja = 1000; break; case SB_LINEUP: if( pozycja > 0 ) { pozycja--; } break; case SB_LINEDOWN: if( pozycja < 1000 ) { pozycja++; } break; case SB_PAGEUP: pozycja -= si.nPage; if( pozycja < 0 ) { pozycja = 0; } break; case SB_PAGEDOWN: pozycja += si.nPage; if( pozycja > 1000 ) { pozycja = 1000; } break; case SB_THUMBPOSITION: pozycja = si.nTrackPos; break; case SB_THUMBTRACK: pozycja = si.nTrackPos; break; } int dy = -( pozycja - si.nPos ); ScrollWindowEx( hStatic, 0, dy,( CONST RECT * ) NULL,( CONST RECT * ) NULL,( HRGN ) NULL,( LPRECT ) NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE ); UpdateWindow( hStatic ); ZeroMemory( & si, sizeof( si ) ); si.cbSize = sizeof( SCROLLINFO ); si.fMask = SIF_POS; si.nPos = pozycja; SetScrollInfo( hScroll, SB_VERT, & si, TRUE ); } break; case WM_COMMAND: switch( wParam ) { case ID_PRZYCISK1: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK2: SetWindowText( hStatic, "" ); break; case ID_PRZYCISK3: SetWindowText( hStatic, "" ); } break; } return 0; }
|
|
xevuel |
» 2013-06-02 12:16:05 Nigdzie nie tworzysz kontrolki o klasie Scrollbar. Twój kod: hPrzycisk1 = CreateWindowEx( 0, "BUTTON", "1", WS_CHILD | WS_VISIBLE, 15, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK1, hInstance, NULL ); hPrzycisk2 = CreateWindowEx( 0, "BUTTON", "2", WS_CHILD | WS_VISIBLE, 300, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK2, hInstance, NULL ); hPrzycisk3 = CreateWindowEx( 0, "BUTTON", "3", WS_CHILD | WS_VISIBLE, 580, 500, 200, 50, hwnd,( HMENU ) ID_PRZYCISK3, hInstance, NULL );
hStatic = CreateWindowEx( 0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | SS_CENTER, 20, 20, 750, 400, hwnd, NULL, hInstance, NULL ); SetWindowText( hStatic, "" ); Wstaw niżej kod z kursu (możesz zmienić wymiary i pozycje; jeśli wkleisz tak jak jest, scrollbar pojawi się przy prawej krawędzi głównego okna, a nie przy kontrolce): RECT okno; GetClientRect( hwnd, & okno ); int iVThumb = GetSystemMetrics( SM_CYVTHUMB ); hScroll = CreateWindowEx( 0, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | SBS_VERT, okno.right - 16, okno.top, 16, okno.bottom - iVThumb, hwnd, NULL, hInstance, NULL ); Aha, trzeba będzie jeszcze zmienić SB_VERT na SB_CTL ( SetScrollInfo( hScroll, SB_VERT, & si, TRUE ); i podobne) i wyrzucić WS_VSCROLL z kontrolki hStatic. |
|
« 1 » 2 |