Alternative zu GetAsyncKeyState()
-
Hi Leute,
ich hab n kleines chat Programm geschrieben: man gibt den text in einer textbox ein, drückt enter, und kriegt den text in der textbox drüber wieder raus. Mein Problem ist jetzt das enter drücken. Mit VK_RETURN hat das iwie nich geklappt, wahrscheinlich weils in der textbox is =(. Deshalb frag ich das ganze jetzt mit GetAsyncKeyState() ab. Die Funktion bringt nur leider ne ziemlich hohe CPU auslastung mit sich. Deshalb wüsst ich gern, wie ich das hinkrieg, dass es etwas "sparender is". Gibts da vllt auch ne windows message oder so?
Würde mich über Hilfe sehr freuen.MfG Daniel
-
Hallo
du musst das editfeld subclassen. dazu änderst du seine WndProc
via SetWindowLong und GWL_WNDPROC als parameter.
(natürich vorher alte prozedur mit GetWindowLong sichern).in deiner funktion kannst du jetzt VK_RETURN behandeln.
Immer am Ende CallWindowProc aufrufen!
-
ach und was muss ich da als dritten parameter verwenden?
jetzt schauts so aus:
SetWindowLongPtr(feld, GWL_WNDPROC, NULL);
stimmt so oder?
-
hm, nein
du musst dir eine WndProc für das Feld schreiben:
LRESULT CALLBACK (*old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK HookProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_KEYDOWN && LOWORD(wParam) == VK_RETURN) mache_was_tolles(); return CallWindowProc(old, hWnd, msg, wParam, lParam); } // in der main: old = GetWindowLong(feld, GWL_WNDPROC); // alte speichern SetWinowLong(feld, GWL_WNDPROC, HookProc); // hier die prozedur einsezten
dann sollte das ganze funktionieren.
edit: natürlich musst du das ganze noch richtig casten, wenn die typen
nicht passen :p
-
das
LRESULT CALLBACK (*old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
mag er nich:
Spiel.cpp|52|error C2059: syntax error : '('|
wenn ichs so mach:
LRESULT CALLBACK *old(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
Spiel.cpp|52|error C2165: 'left-side modifier' : cannot modify pointers to data|und so:
LRESULT CALLBACK old(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
old = GetWindowLong(feld, GWL_WNDPROC); // alte speichern
Spiel.cpp|246|error C2659: '=' : overloaded function as left operand|wie muss ich das machen? o.O
-
sry aber ich hab noch keinen kompiler im kopf
LRESULT (CALLBACK *old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
ich glaub ich bin zu blöd dafür
bei der funktion GetWindowLongPtr:
error C2440: '=' : cannot convert from 'LONG' to 'LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)'|
wenn ich als typ LONG_PTR nehm klappt zwar der rückgabewert der funktion aber dafür bei dem return nich mehr
-
killmichnich schrieb:
ich glaub ich bin zu blöd dafür
ja
-
ich hab doch gesagt casten!
wenn ein long nicht in ein 'LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)'
passt, müssen wir es halt reinquetschen:old = reinterpret_cast<LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)>(blabla);
-
ok thx für die noob-hilfe, jetzt krieg ich keine errors mehr, aber wenn ich das Programm start is die textbox nich mehr da o.O
fehlt da noch irgendwas?
-
zeig uns bitte deinen code, dieses ratespiel ist zu mühselig. leitest du alles was du nicht behandelst an die alte wndproc weiter?
-
ich habs jetzt so gemacht wie er gesagt hat:
LRESULT (CALLBACK *old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK HookProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_KEYDOWN && LOWORD(wParam) == VK_RETURN) //mache_was_tolles(); return CallWindowProc(old, hWnd, msg, wParam, lParam); } old = reinterpret_cast<LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)>(GetWindowLongPtr(feld, GWL_WNDPROC)); // alte speichern SetWindowLongPtr(feld, GWL_WNDPROC, reinterpret_cast<long>(HookProc));
-
zeig uns bitte genug code um es reproduzierbaren zu können. bei dem code, wie du ihn geposted hast, ist es klar, daß es nicht funktioniert, weil CallWindowProc() nur aufgerufen wird wenn (msg == WM_KEYDOWN && LOWORD(wParam) == VK_RETURN)
-
ok sry:
HWND CreateMainWindow(HINSTANCE hInstance); HWND activewindow; // Callback Funktion zur Nachrichtenbehandlung LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); //LRESULT (CALLBACK *old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT (CALLBACK *old)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK HookProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_KEYDOWN && LOWORD(wParam) == VK_RETURN) //mache_was_tolles(); return CallWindowProc(old, hWnd, msg, wParam, lParam); } // Das Fensterhandle HWND hWnd = 0; static HWND feld; // Windows main-Funktion int WINAPI WinMain(HINSTANCE hInstance, // Handle der Programminstanz HINSTANCE hPrevInstance, // Handle der letzten Instanz LPSTR lpCmdLine, // Kommandozeile int nCmdShow) // Art wie das Fenster angezeigt werden soll { // Fenster erzeugen und Handle speichern //MessageBox(NULL, "Druecke A und D um dich nach links und rechts zu bewegen\nEsc zum beenden", NULL, MB_OK); hWnd = CreateMainWindow(hInstance); // Wenn der Rueckgabewert 0 ist, ist ein Fehler aufgetreten if(0 == hWnd) { MessageBox(0, "Fenster konnte nicht erzeugt werden", "Fehler", MB_OK); return -1; } MSG msg; // Diese Schleife laeuft bis die Nachricht WM_QUIT empfangen wird while (GetMessage (&msg, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&msg); /* Send message to WindowProcedure */ DispatchMessage(&msg); } // Rueckgabewert an Windows return 0; } HWND CreateMainWindow(HINSTANCE hInstance) { WNDCLASSEX wndClass = { sizeof(WNDCLASSEX), // Groesse angeben CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW, // Standardstile MessageHandler, // Callback-Funktion 0, // Zusaetzliche Angaben 0, // nicht benoetigt hInstance, // Anwendungsinstanz LoadIcon(NULL, IDI_WINLOGO), // Windows-Logo LoadCursor(NULL, IDC_ARROW), // Normaler Cursor (HBRUSH)GetStockObject(WHITE_BRUSH), // Weisser Pinsel NULL, // kein Menue "WindowClass", // Der Name der Klasse LoadIcon(NULL, IDI_WINLOGO) // Windows Logo }; // Klasse registrieren RegisterClassEx(&wndClass); return CreateWindowEx(NULL, // Keine erweiterten Stile nutzen "WindowClass", // Klassenname "Surface", // Fenstertitel WS_OVERLAPPEDWINDOW | // Fenster WS_VISIBLE, // Eigenschaften 0, 0, // Anfangsposition 1024, 768, // und Groesse des Fensters NULL, // Handle des Elternfensters NULL, // Handle des Menues hInstance, // Anwendungsinstanz NULL); // wird nicht benoetigt } // Diese Funktion wird von Windows aufgrufen, wenn // eine Nachricht fuer Ihr Programm vorliegt LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: { //feld=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", text.c_str(), WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 20, 450, 784, 200, hwnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); old = reinterpret_cast<LRESULT (__stdcall *)(HWND,UINT,WPARAM,LPARAM)>(GetWindowLongPtr(feld, GWL_WNDPROC)); // alte speichern break; } // Programm beenden, wenn das Fenster // geschlossen wird case WM_DESTROY: PostQuitMessage(0); return 0; break; case WM_COMMAND: { if (lParam == (LPARAM)button) { if (HIWORD(wParam) == BN_CLICKED) { ShowWindow(feld, SW_SHOW); SetWindowLongPtr(feld, GWL_WNDPROC, reinterpret_cast<long>(HookProc)); } } break; } case WM_TIMER: { if(hWnd==GetActiveWindow()) { KillTimer(hWnd, 1); flash=false; FlashWindow(hWnd, flash); } else { if(flash) { flash=false; } else if(!flash) { flash=true; } } FlashWindow(hWnd, flash); break; } case WM_KEYDOWN: switch(wParam) { case VK_RETURN: { char ctext[256]; memset(&ctext, NULL, sizeof(ctext)); for(int i=0; i<sizeof(ctext); i++) { ctext[i]=NULL; } GetWindowText(feld, ctext, sizeof(ctext)); send(s1, ctext, strlen(ctext), 0); SetWindowText(feld, NULL); break; } case VK_ESCAPE: CloseHandle(threadHandle); DeleteCriticalSection(&g_csPrint); PostQuitMessage(0); break; } break; } // Standardnachrichtenverarbeitung von Windows return DefWindowProc(hwnd, msg, wParam, lParam); }
das dürfte alles relevante sein, oder?
-
so hier
WNDPROC oldProc; // ... // ... hWndEdit = GetDlgItem(hDlg, IDC_EDIT1); oldProc = SetWindowLong(hWndEdit, GWL_WNDPROC, EditProc); // ... // ... LRESULT CALLBACK EditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_GETDLGCODE: if(wParam == VK_RETURN) return DLGC_WANTMESSAGE; break; case WM_KEYDOWN: if(wParam == VK_RETURN) { MessageBox(hWnd,_T("VK_RETURN received!"),NULL,MB_OK); return 0; } break; } return CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); }
siehe auch martins blog http://blog.m-ri.de/?s=subclass
-
also sry asdca, ich hab das wieder nich ganz geblickt welches HWND ich da wo einsetzen muss. aber ich will ja nich weiter nerven.
Ich hatte nen geistesblitz und hab das jetzt einfach so gemacht:while (GetMessage (&msg, NULL, 0, 0)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&msg); /* Send message to WindowProcedure */ if(msg.message==WM_KEYDOWN && msg.wParam==VK_RETURN) { char ctext[256]; memset(&ctext, NULL, sizeof(ctext)); for(int i=0; i<sizeof(ctext); i++) { ctext[i]=NULL; } GetWindowText(feld, ctext, sizeof(ctext)); send(s1, ctext, strlen(ctext), 0); SetWindowText(feld, NULL); } else if(msg.wParam!=VK_RETURN) { DispatchMessage(&msg); } }
so geht das doch auch oder?