berkov Temat założony przez niniejszego użytkownika |
[WinAPI] Odbieranie powiadomień EN_UPDATE i EN_CHANGE » 2013-04-21 01:00:33 hey ho Mam Dialog a w nim rozne Controls. Dla potrzeb przykladu zalozmy ze mowa o: #define IDC_przyklad 1001 IDC_przyklad to EDITTEXT. Dialog na ktorym sie Control znajduje obslugiwany jest przez: BOOL CALLBACK DlgProcModalless( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) Chcialbym miec mozliwosc korekty wpisu uzytkownia w tym Control'u, ponownie dla przykladu, tak aby program automatycznie poprawil wpis uzytkownika z "x" na "z" oraz aby nie pozwolil wpisac literki "a". w MSDN jest: EN_UPDATE WPARAM wParam; LPARAM lParam;
Parameters wParam - The LOWORD contains the identifier of the edit control. The HIWORD specifies the notification code. lParam - A handle to the edit control. |
Tylko jak to sie ma do mojego DlgProcModalless? Poczatek kodu (nie wiem wogole czy dobrze): BOOL CALLBACK DlgProcModalless( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { switch( Msg ) { case EN_UPDATE: { switch( LOWORD( lParam ) ) { case 1001:
Rozumiem uzycie notification codes ale tylko do poziomu lParam albo wParam, ale jak sie dostac dalej (LOWORD, HIWORD)...? Czyli na tym konkretnym przykladzie jak dostac HWND do danego Control'u i jak dowiedziec sie o tym ze uzytkownik np wpisal "x" z klawiatury? dzieki berkov |
|
DejaVu |
» 2013-04-21 01:11:28 a co zrobisz w przypadku, gdy ktoś zrobi ctrl+v? Nie ma sensu czaić się na konkretne wciśnięcie klawisza, bo ctrl+v takie 'zabezpieczenie' po prostu ominie. |
|
berkov Temat założony przez niniejszego użytkownika |
» 2013-04-21 01:25:10 Juz teraz nie pamietam ktora z dwoch notyfications CHANGE czy UPDATE, ale pamietam ze gdzies wyczytalem ze kteoras z nich obejmuje zmiany rozumiane jako rowniez wklejanie ze schowka. poza tym logicznie myslac CTR+V to "zmiana", wiec tym bym sie narazie nie martwil. Przynajmniej pocwicze notyfication codes |
|
Monika90 |
» 2013-04-21 07:51:18 Sprawdzenie w dokumentacji zabiera aż minutę: EN_UPDATE: The parent window of the edit control receives this notification message through the WM_COMMAND message.
|
|
|
xevuel |
» 2013-04-21 07:53:51 The parent window of the edit control receives this notification code through a WM_COMMAND message. |
wParam The LOWORD contains the identifier of the edit control. The HIWORD specifies the notification code. lParam A handle to the edit control.
|
Czyli odbierasz WM_COMMAND, porównujesz identyfikator/uchwyt kontrolki (czy jest to ten, który ma być, a nie np. innego Edita) a następnie: switch( HIWORD( wParam ) ) { case EN_UPDATE: break; }
|
|
berkov Temat założony przez niniejszego użytkownika |
» 2013-04-21 09:54:29 Hey ho! @Monika90 - "dzieki serdecznie" za fatyge ale kompletnie nie pomoglas! Jak powiedzialem czytalem dokumentacje ale jej nie zrozumialem, dla poczatkujacych zrozumienie takich "referencji" moze byc dosc ciezkie, dlatego tez wlozylem post na tym forum. Nie pamieta wol jak cieleciem byl! @xevuel, dzieki, teraz juz rozumiem ze EN_UPDATE to HIWORD( wParam ) pochodzacy z Msg WM_COMMAND. Myslalem ze EN_UPDATE to Msg i sam przynosi lParam i wParam. Wpisalem wiec taki kod: BOOL CALLBACK DlgProcModalless( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { switch( Msg ) { case WM_COMMAND: { switch( LOWORD( wParam ) ) { case IDC_zapisz: jakiskodzapisujacy(); break; case IDC_anuluj: DestroyWindow( hwnd ); break; case IDC_przyklad: { if( HIWORD( wParam ) == EN_UPDATE ) { MessageBox( 0, "zmodyfikowano text", 0, 0 ); } else { MessageBox( 0, "Wszystko pozostale", 0, 0 ); } } break; } } break; default: return FALSE; } return TRUE; } Ale cos dalej nie dziala, bo po odpaleniu tego kodu jak tylko klikne mysza na Control IDC_przyklad dostaje z jakies 30 razy TYLKO pop-up "Wszystko pozostale" a jak juz sie "uspokoi" i wpisuje cos z klawiatury to nie ma wogole zadnej reakcji. Co dziwniejsze - jesli klikne na inny kontrol i wroce kliknieciem spowrotem to rowniez juz nie dostane zadnego komunikatu. Czyli dziala tylko 30x (i to zle) za pierwszym kliknieciem a pozniej nic i nigdy nie wyrzuca "zmodyfikowano text". jakis pomysl? berkov |
|
xevuel |
» 2013-04-21 11:31:27 Kod wydaje się być prawidłowy.. Stwórz jak najkrótszy, ale kompletny przykład który zachowuje się jak mówisz.
//Edit: Weź pod uwagę, że wywołanie MessageBoxa spowoduje wysłanie EN_SETFOCUS i EN_KILLFOCUS. Do takiego "debugowania" lepiej użyć funkcji która nie wymaga interakcji z użytkownikiem (najbanalniejszy przykład - SetWindowText dla głównego okna). |
|
berkov Temat założony przez niniejszego użytkownika |
» 2013-04-21 12:25:01 ok, masz racje, MessageBox powodowal "samowywolanie" i zapetlenie wiec wprowadzilem male zmiany BOOL CALLBACK DlgProcModalless( HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam ) { switch( Msg ) { case WM_COMMAND: { switch( LOWORD( wParam ) ) { case IDC_zapisz: jakiskod(); break; case IDC_anuluj: DestroyWindow( hwnd ); break; case IDC_przyklad: { if( HIWORD( wParam ) == EN_UPDATE ) { MessageBox( 0, "EN_UPDATE!", 0, 0 ); } else { MessageBeep( 0 ); } } break; } } break; default: return FALSE; } return TRUE; } Teraz dostaje system beep za kazdym dotknieciem, zmiana lub opuszczeniem IDC_example Control, przynajmniej teraz to tylko jedno beepniecie a nie jak wczesniej niekonczace sie wywolanie MessageBox wiec jakis postep jest. Ale nadal nie dostaje MessageBoxu ani raz, nie rozumiem. Czyzby naprawde EN_UPDATE niegdy nie byl przekazywany? Jesli tak to czy mozna sprawdzic jaki inny komunikat jest przekazywany? W razie czego Dialog wywoluje tak: hDialogMen = CreateDialog( GetModuleHandle( 0 ), MAKEINTRESOURCE( 1000 ), hwMain, DlgProcModalless ); ShowWindow( hDialogMen, SW_SHOW ); resources.rc: LANGUAGE 0, SUBLANG_NEUTRAL IDD_FVT DIALOGEX 0, 0, 319, 200 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU CAPTION "Dialog" FONT 8, "Verdana" { PUSHBUTTON "Anuluj", IDC_zapisz, 35, 160, 60, 14, WS_TABSTOP DEFPUSHBUTTON "Zapisz", IDC_anuluj, 242, 160, 60, 14, WS_TABSTOP EDITTEXT IDC_przyklad, 214, 73, 55, 14, ES_AUTOHSCROLL | WS_TABSTOP } resources.h: #define IDC_OK 103 #define IDC_CANCEL 104 #define IDD_DYNAMIC 222 #ifndef IDC_STATIC #define IDC_STATIC (-1) #endif #define IDC_przyklad 1001 #define IDD_zapisz 1002 #define IDD_anuluj 1003 btw. probowalem rowinez z EN_CHANGE i efekt taki sam jak z EN_UPDATE. |
|
« 1 » 2 |