How do I know when the Backspace is pressed in a combobox?
Printable View
How do I know when the Backspace is pressed in a combobox?
you should get a WM_KEYDOWN 8
Yes I should, but I is a combobox so I don't get that message. I may need to subclass it but I don't know.
yeah, that would do
What do you mean you don't know how to subclass it. It is not VB.
Just handle that message in the WindowProc.
Try this:
Add these to your globals
Add these to the WM_CREATE and WM_CLOSE events of your main WinProc.Code:LRESULT CALLBACK ComboBoxProc(HWND, UINT, WPARAM, LPARAM);
WNDPROC wOldProc;
This will be your ComBox procedure:Code:case WM_CREATE:
{
hCbo = CreateWindowEx(NULL, "ComboBox", NULL, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE, 32, 32, 128, 128, hWnd, NULL,gInst,NULL);
SendMessage(hCbo, CB_ADDSTRING, 0, (LPARAM) "Zero");
SendMessage(hCbo, CB_ADDSTRING, 0, (LPARAM) "One");
SendMessage(hCbo, CB_ADDSTRING, 0, (LPARAM) "Two");
// Subclass it
wOldProc = (WNDPROC)SetWindowLong(hCbo, GWL_WNDPROC, (LONG) &ComboBoxProc);
return 0;
}
case WM_CLOSE:
SetWindowLong(hCbo, GWL_WNDPROC, (LONG)wOldProc);
DestroyWindow(hWnd);
return 0;
Code:LRESULT CALLBACK ComboBoxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if( (uMsg == WM_KEYDOWN) && (wParam == 8) )
{
// Add code here
MessageBox(NULL, "Backspace pressed", NULL, NULL);
}
return CallWindowProc(wOldProc, hWnd, uMsg, wParam, lParam);
}
No, you can't capture the messages of the combobox from the window procedure of the parent.Quote:
Originally posted by Vlatko
What do you mean you don't know how to subclass it. It is not VB.
Just handle that message in the WindowProc.
Thanks megatron. I think I was doing some think wrong when handling the "WM_KEYDOWN" message after subclassing.
It is almost autocomplete now but there is just one more problem:
First look at the image
I have some words in the combobox like "C:\", "C:\windows". When I type "C", it completes with the mathcing word which is "C:\", and then it heighlights ":\" as it does in the other autocomplete comboboxes.
Now the problem is that I can't move the caret using the left/right arrow keys...you know
Here is the code I am using in the CB_EDITUPDATE message that actually completes the word:
isback is a global variable that tells if the backspace is pressed or not. Here is code that I am using to tell if it is pressed or not using the subclassing technique:PHP Code:char edtext[2];
USHORT theindex;
case CBN_EDITCHANGE:
if(!isback)
{
GetWindowText(cbhwnd, edtext, GetWindowTextLength(cbhwnd) + 1);
if(SendMessage(cbhwnd, CB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPCSTR)edtext) != CB_ERR)
{
theindex = GetWindowTextLength(cbhwnd);
SendMessage(cbhwnd,CB_SETCURSEL, SendMessage(cbhwnd, CB_FINDSTRING, (WPARAM)-1, (LPARAM)(LPCSTR)edtext), 0);
SendMessage(cbhwnd, CB_SETEDITSEL,0, MAKELPARAM(theindex,GetWindowTextLength(cbhwnd)));
}
}
return TRUE;
So, why can't I move the caret using the arrow keys so that I don't have to type the whole word if it highlights it?PHP Code:switch(msg)
{
case WM_KEYDOWN:
if(wparam == 8)
{
isback = TRUE;
}
else
{
isback = FALSE;
}
return 0;
}
It is ok now. I used the message "WM_KEYUP" instead of "WM_KEYDOWN" and it is all working now
Thanks a lot!:D
Ohhh NO!
I got the caret thingy working but then I lots the backspace handling. How do I get both at a time?
I am using the same code except that I am handling the "WM_KEYUP" message instead of "WM_KEYDOWN"
I know that Megatron. I didn't mean the WindowProc of the parent but the combobox's own procedure.Quote:
No, you can't capture the messages of the combobox from the window procedure of the parent.
this thread is stopped:confused: Come on guys, it is not finished yet. I still have the above problem
For some reason, my subclassing isnt working right. I'm trying to do this too, but for some reason, it isnt working. Code:
Any ideas?Code:#include <windows.h>
const char g_szClassName[] = "myWindowClass";
#define IDC_COMBOBOX 9001
#define FixFonts(control) {SendDlgItemMessage(hwnd, control, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));}
HINSTANCE hInstance;
WNDPROC wOldProc;
LRESULT CALLBACK ComboBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYUP:
MessageBox(hwnd,"","",0);
break;
default:
return(DefWindowProc(hwnd,uMsg,wParam,lParam));
}
return(0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
SetWindowLong(GetDlgItem(hwnd,IDC_COMBOBOX), GWL_WNDPROC, (LONG)wOldProc);
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
CreateWindow("COMBOBOX","",WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,0,0,100,100,hwnd,(HMENU)IDC_COMBOBOX,hInstance,0);
FixFonts(IDC_COMBOBOX);
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "Zero");
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "One");
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "Two");
wOldProc = (WNDPROC)SetWindowLong(GetDlgItem(hwnd,IDC_COMBOBOX), GWL_WNDPROC, (LONG) &ComboBoxProc);
SetWindowLong(GetDlgItem(hwnd,IDC_COMBOBOX), GWL_STYLE , WS_CHILD | WS_VISIBLE | CBS_DROPDOWN);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
::hInstance=hInstance;
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_BTNFACE+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0,
g_szClassName,
"Autocomplete Combobox Test",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Try this code. I have put the comments on which line is added or changed:
PHP Code:#include <windows.h>
const char g_szClassName[] = "myWindowClass";
#define IDC_COMBOBOX 9001
#define FixFonts(control) {SendDlgItemMessage(hwnd, control, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));}
HINSTANCE hInstance;
WNDPROC wOldProc;
//A new declaration for the Handle of the editbox in the combobox
HWND edhwnd;
LRESULT CALLBACK ComboBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_KEYUP:
MessageBox(hwnd,"","",0);
break;
default:
return CallWindowProc(wOldProc, hwnd,uMsg,wParam,lParam); //Changed to CallWindowProc
}
return(0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
//This is also changed. Changed the handle to editbox handle
SetWindowLong(edhwnd, GWL_WNDPROC, (LONG)wOldProc);
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
CreateWindow("COMBOBOX","",WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,0,0,100,100,hwnd,(HMENU)IDC_COMBOBOX,hInstance,0);
FixFonts(IDC_COMBOBOX);
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "Zero");
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "One");
SendMessage(GetDlgItem(hwnd,IDC_COMBOBOX), CB_ADDSTRING, 0, (LPARAM) "Two");
//New Stuff Added here
//We get the handle of the editbox in the combobox because that
//is the window in which WM_KEYUP message occurs
POINT pt;
pt.x = 3;
pt.y = 3;
edhwnd = ChildWindowFromPoint(GetDlgItem(hwnd,IDC_COMBOBOX), pt);
//-----------------------------------------------------------
//Now we use the editbox handle - not the combobox handle
wOldProc = (WNDPROC)SetWindowLong(edhwnd, GWL_WNDPROC, (LONG) &ComboBoxProc);
SetWindowLong(GetDlgItem(hwnd,IDC_COMBOBOX), GWL_STYLE , GetWindowLong(GetDlgItem(hwnd,IDC_COMBOBOX), GWL_STYLE) | WS_CHILD | WS_VISIBLE | CBS_DROPDOWN); //Changed this line
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
::hInstance=hInstance;
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_BTNFACE+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0,
g_szClassName,
"Autocomplete Combobox Test",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
//--------------------------------------------------------------------------------