mlodymichal1990 Temat założony przez niniejszego użytkownika |
Kurs WinAPI - okna dialogowe » 2016-07-16 13:36:59 Ostatnio czytam kurs: http://cpp0x.pl/kursy/Kurs-WinAPI-C++/167 . Na rozdziałach o oknach dialogowych zaczęły się schody, których nie mogę przezwyciężyć. Wiem, że na dole każdego rozdziału widnieje info, że kody mogą być nieaktualne, więc może to jest powodem. Część kodów mi się w ogóle nie kompiluje, a część się kompiluje, ale nie działa. Do rzeczy. Rozdział 9. Kod nie działał mi, tzn. okno dialogowe się nie wyświetlało. W końcu znalazłem rozwiązanie, należało w linijce: STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION dołożyć: WS_VISIBLE. Tutaj moja sugestia do administratorów, aby poprawić ten kod, coby podobni do mnie początkujący programiści niepotrzebnie nie irytowali się i nie tracili swojego czasu :) Rozdział 12. Podobna sytuacja - kompilacja zakończona sukcesem, niestety dialog nie wyświetla się. Wklejam cały kod. #include <windows.h> #include "pasek.h"
LPSTR NazwaKlasy = "Klasa Okienka"; MSG msg; LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); BOOL CALLBACK DlgProc( HWND, UINT, WPARAM, LPARAM ); HWND hpasek; HFONT g_hfnNowy; LPSTR bufor, bufor2; UINT WM_FINDREPLACE; FINDREPLACE fr;
int WINAPI WinMain( HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil ) { WNDCLASSEX wc; wc.cbSize = sizeof( WNDCLASSEX ); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hThisInstance; 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 ) ) { MessageBox( NULL, "Wysoka Komisja odmawia rejestracji tego okna!", "Niestety...", MB_ICONEXCLAMATION | MB_OK ); return 1; } WM_FINDREPLACE = RegisterWindowMessage( FINDMSGSTRING ); HWND hwnd; hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, NazwaKlasy, "Oto okienko", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 600, 400, NULL, NULL, hThisInstance, NULL ); RECT rcClient; GetClientRect( hwnd, & rcClient ); #define ID_PLIK 501 hpasek = CreateWindowEx( 0, "BUTTON", "Dialog", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, rcClient.bottom - 27, 50, 25, hwnd,( HMENU ) ID_PLIK, hThisInstance, NULL ); if( hwnd == NULL ) { MessageBox( NULL, "Okno odmówiło przyjścia na świat!", "Ale kicha...", MB_ICONEXCLAMATION ); return 1; } ShowWindow( hwnd, nFunsterStil ); while( GetMessage( & msg, NULL, 0, 0 ) ) { TranslateMessage( & msg ); DispatchMessage( & msg ); } return msg.wParam; }
LRESULT CALLBACK WndProc( HWND hwnd, UINT mesg, WPARAM wParam, LPARAM lParam ) { switch( mesg ) { case WM_COMMAND: { if( wParam != ID_PLIK ) break; ZeroMemory( & fr, sizeof( FINDREPLACE ) ); fr.lStructSize = sizeof( FINDREPLACE ); fr.hwndOwner = hwnd; fr.lpstrFindWhat = bufor; fr.wFindWhatLen = 80; fr.lpstrReplaceWith = bufor2; fr.wReplaceWithLen = 80; fr.Flags = FR_HIDEUPDOWN | FR_NOMATCHCASE | FR_HIDEWHOLEWORD; lstrcpy( bufor, "tekst" ); lstrcpy( bufor2, "inny tekst" ); FindText( & fr ); ShowWindow( hwnd, SW_SHOW ); } break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: if( mesg == WM_FINDREPLACE ) { FINDREPLACE * fr =( FINDREPLACE * ) lParam; if( fr->Flags & FR_FINDNEXT ) { MessageBox( hwnd, "Nic nie znaleziono.", NULL, MB_ICONINFORMATION ); } } else { return DefWindowProc( hwnd, mesg, wParam, lParam ); } } return 0; }
BOOL CALLBACK DlgProc( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { switch( Msg ) { case WM_COMMAND: { } break; default: return FALSE; } return TRUE; }
Rozdział 13. W procedurze hakowej pojawia się instrukcja: SendMessage( hdlg, CDM_GETFILEPATH, sizeof( buffer ),( LPARAM ) & buffer ); buffer nigdzie powyżej nie jest zdeklarowane i jest błąd kompilacji. Z kontekstu całości wnioskuję, że jest to string zawierający nazwę pliku i że "pobieramy" go ze struktury OPENFILENAME. Nie mam natomiast pojęcia, jak to "wykodzić". Podobnie instrukcja: assert( g_hDCMem ); Mój kompilator nie zna funkcji assert, nigdzie powyżej nie jest zdefiniowana. Rozdział 14. Kompilacja zakończona sukcesem - dialog nie wyświetla się, WS_VISIBLE nie pomogło. #include <windows.h>
LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM ); BOOL CALLBACK DialogProc( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam );
char szClassName[] = "CodeBlocksWindowsApp"; HGLOBAL hgbl; DLGTEMPLATE * pdt; DLGITEMTEMPLATE * pdit; WORD * pw; LPWSTR pws; int nchar; void PixelsToDialogUnits( RECT & rc ); WORD * lpwAlign( WORD * in );
int WINAPI WinMain( HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow ) { HWND hwnd; MSG messages; WNDCLASSEX wincl; wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; wincl.style = CS_DBLCLKS; wincl.cbSize = sizeof( WNDCLASSEX ); wincl.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wincl.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); wincl.hCursor = LoadCursor( NULL, IDC_ARROW ); wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground =( HBRUSH ) COLOR_BACKGROUND; if( !RegisterClassEx( & wincl ) ) return 0; hwnd = CreateWindowEx( 0, szClassName, "Code::Blocks Template Windows App", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL ); hgbl = GlobalAlloc( GMEM_ZEROINIT, 1024 ); pdt =( DLGTEMPLATE * ) GlobalLock( hgbl ); pdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | WS_VISIBLE; pdt->cdit = 2; RECT rcDlg = { 10, 10, 200, 150 }; PixelsToDialogUnits( rcDlg ); pdt->x =( short ) rcDlg.left; pdt->y =( short ) rcDlg.top; pdt->cx =( short ) rcDlg.right; pdt->cy =( short ) rcDlg.bottom; pw =( WORD * )( pdt + 1 ); * pw++ = 0x0; * pw++ = 0x0; pws =( LPWSTR ) pw; nchar = 1 + MultiByteToWideChar( CP_ACP, 0, "Mój dialog", - 1, pws, 50 ); pw += nchar; pw = lpwAlign( pw ); pdit =( DLGITEMTEMPLATE * ) pw; RECT rcBtn = { 50, 100, 100, 25 }; PixelsToDialogUnits( rcBtn ); pdit->x =( short ) rcBtn.left; pdit->y =( short ) rcBtn.top; pdit->cx =( short ) rcBtn.right; pdit->cy =( short ) rcBtn.bottom; pdit->id = IDOK; pdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; pw =( WORD * )( pdit + 1 ); * pw++ = 0xffff; * pw++ = 0x0080; pws =( LPWSTR ) pw; nchar = 1 + MultiByteToWideChar( CP_ACP, 0, "OK", - 1, pws, 50 ); pw += nchar; * pw++ = 0; pw = lpwAlign( pw ); pdit =( DLGITEMTEMPLATE * ) pw; RECT rcEdit = { 25, 10, 150, 25 }; PixelsToDialogUnits( rcEdit ); pdit->x =( short ) rcEdit.left; pdit->y =( short ) rcEdit.top; pdit->cx =( short ) rcEdit.right; pdit->cy =( short ) rcEdit.bottom; pdit->id = 1000; pdit->style = WS_CHILD | WS_VISIBLE | WS_BORDER; pw =( WORD * )( pdit + 1 ); * pw++ = 0xffff; * pw++ = 0x0081; pws =( LPWSTR ) pw; nchar = 1 + MultiByteToWideChar( CP_ACP, 0, "Tekst", - 1, pws, 50 ); pw += nchar; * pw++ = 0; GlobalUnlock( hgbl ); DialogBoxIndirect( hThisInstance,( DLGTEMPLATE * ) hgbl, hwnd,( DLGPROC ) DialogProc ); ShowWindow( hwnd, SW_SHOW ); ShowWindow( hwnd, nCmdShow ); while( GetMessage( & messages, NULL, 0, 0 ) ) { TranslateMessage( & messages ); DispatchMessage( & messages ); } return messages.wParam; }
LRESULT CALLBACK WindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hwnd, message, wParam, lParam ); } return 0; }
BOOL CALLBACK DialogProc( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { return false; }
void PixelsToDialogUnits( RECT & rc ) { LONG base = GetDialogBaseUnits(); int baseX = LOWORD( base ); int baseY = HIWORD( base ); rc.left = MulDiv( rc.left, 4, baseX ); rc.right = MulDiv( rc.right, 4, baseX ); rc.top = MulDiv( rc.top, 8, baseY ); rc.bottom = MulDiv( rc.bottom, 8, baseY ); }
WORD * lpwAlign( WORD * in ) { ULONG_PTR ul =( ULONG_PTR ) in; ul += 3; ul >>= 2; ul <<= 2; return( WORD * ) ul; } Zastanawiam się, czy mam problemy, bo kurs jest nieaktualny, czy ja coś źle robię. Jeżeli to pierwsze, to czy jest ktoś w stanie polecić jakiś inny dobry kurs? Proszę o pomoc. |