Capturing keyboard input on a List View control, C++ - c++

How do I capture key presses when a list view control has focus?
My window creation code looks like
// Window creation
HWND hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_APPWINDOW, g_szClassName, "Test", WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 209, 351, 0, 0, hInstance, 0);
HWND hwnd_list = CreateWindowEx(0, WC_LISTVIEW, "", WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_EX_FULLROWSELECT, 1, 246, 201, 55, hwnd, (HMENU)IDL_LISTVIEW, hInstance, 0);
Inside WndProc I process the WM_KEYPRESS message and create a MessageBox displaying the virtual code, but its only triggering when I press keys after clicking outside the list view.

You'll need to take a look at control subclassing, http://msdn.microsoft.com/en-us/library/bb773183%28VS.85%29.aspx.
If you're using MFC, it's a bit less painful. (Back in the day when Borland was still alive, it was a breeze in OWL, but that's ancient history.)

You need to subclass the listview proc and then use 'WM_KEYDOWN' to capture the input.

Related

Newline on win32 gui textbox when using SetWindowText

I create a textbox on a win32 gui app. Later on I'm trying to set a text to it but newline "\n" isn't working when using SetWindowText
g_ButtonManager.hWndThirtyText = CreateWindowExW(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""),
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE,
10, 95, //x,y
200, 60, //width, height
hWnd, (HMENU)IDM_THIRTYTEXT, NULL, NULL);
Even though I:
SetWindowTextA(g_ButtonManager.hWndThirtyText, "Hello\nThere");
It displays HelloThere in the same line.
---Edit
Even with | ES_WANTRETURN
g_ButtonManager.hWndThirtyText = CreateWindowExW(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT("Hello\nMy\nFriend"),
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_WANTRETURN,,
10, 95, //x,y
200, 60, //width, height
hWnd, (HMENU)IDM_THIRTYTEXT, NULL, NULL);
Will not work.
Oh, I figured it.
\r\n is required for a newline.

WinApi Color Listbox

I am trying to modify the color of items in my Listbox.
I use WinApi C++ in Visual Studio 2017.
To create my listbox, I wrote that code:
hListbox = CreateWindowW(L"Listbox", L"My Listbox", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP | WS_BORDER | LBS_EXTENDEDSEL, 100, 60, 300, 2400, hWnd, NULL, NULL, NULL);
Add the items:
SendMessage(hListbox, LB_ADDSTRING, NULL, (LPARAM)Text); (...)
Is it possible to change the color of the text or the background, without changing the type of my object? Or is there an other easy way to create a listbox with colored items?

C++ Dialog Box TAB key not working

I have tried everything but couldn't get the TAB key working to move the focus from one control to another control in a resource dialog. Here is the code:
IDD_DLG_DIALOG DIALOGEX 0, 0, 219, 198
STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_EX_CONTROLPARENT
EXSTYLE WS_EX_APPWINDOW
CAPTION "Caption"
FONT 8, "Tw Cen MT", 400, 0, 0x0
BEGIN
DEFPUSHBUTTON "Done",IDOK,162,175,50,16
EDITTEXT IDC_EDIT1,27,13,185,12,ES_AUTOHSCROLL | WS_TABSTOP | WS_VISIBLE | WS_CHILD
PUSHBUTTON "Add",IDC_Add,109,30,33,13,WS_TABSTOP | WS_VISIBLE | WS_CHILD
LISTBOX IDC_LIST1,7,49,205,121,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP | WS_VISIBLE | WS_CHILD
EDITTEXT IDC_EDIT2,27,31,81,12,ES_AUTOHSCROLL | WS_TABSTOP | WS_VISIBLE | WS_CHILD
LTEXT "Name",IDC_STATIC,7,33,18,11
LTEXT "Link",IDC_STATIC,7,15,15,11
PUSHBUTTON "Delete",IDC_DEL,144,30,33,13 | WS_TABSTOP | WS_VISIBLE | WS_CHILD
CONTROL "Autorun at startup",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,174,70,10
PUSHBUTTON "Edit",IDC_EDIT,179,30,33,13,WS_TABSTOP | WS_VISIBLE | WS_CHILD
END
Main While loop:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow)) return FALSE;
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_STEALTHDIALOG);
while (GetMessage(&msg, NULL, 0, 0))
{
if((!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))||(!IsDialogMessage(msg.hwnd,&msg)))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
Please identify the problem here. Thanks.
Change your || to a &&. At the moment, if TranslateAccelerator returns 0 (which it will unless an accelerator key has been pressed), IsDialogMessage will never be called - and that's what handles the tab key.
(Additionally, as Marco A. implies in his answer, you should pass the HWND of your dialog, and not msg.hwnd as the first parameter of the IsDialogMessage call. But this is immaterial unless IsDialogMessage actually gets called, which it almost always won't while you have || instead of &&).
According to this post and confirmed by this kb article:
TranslateAccelerator() sends WM_COMMAND messages to the window whose
handle you pass as an argument to TranslateAccelerator().
You are probably calling TranslateAccelerator() passing the hwnd member
of your MSG structure; this will be the handle of the window that has
the focus. You should pass the handle of your main windows instead.
And that applies to your code.

Win 32 API, drawing two child windows with vertical splitter bar

Below is code, which I am using for creating child windows:
case WM_CREATE:
hInst = ((LPCREATESTRUCT) lParam) -> hInstance;
hWnd1 = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_LEFT,
"edit", NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_MULTILINE | WS_VSCROLL,
0, 0, 0, 0,
hWnd, (HMENU) 1,
hInst, NULL );
hWnd2 = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_LEFT,
"edit", NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_MULTILINE | WS_VSCROLL,
0, 0, 0, 0,
hWnd, (HMENU) 2,
hInst, NULL );
But this code produces horizontal splitter, and I want vertical splitter.
First I thought, if I change height and width parameters, I could create vertical splitter. But it was of no use.
For full code and sample example (in order to save space on SO):
http://old.sumitbirla.com/software/src/splitter.c
So, what is exactly keyword/parameter, which would produce vertical splitter bar.
The code you posted just creates two child windows. It has nothing to do with vertical or horizontal splitter. Handle the WM_SIZE message in the parent window to position and size the child windows for a vertical or horizontal split.

EDIT control text overflow

This is simple. I created an EDIT control like this:
HWND MYTEXT= CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD|WS_VISIBLE|ES_LEFT|ES_MULTILINE,
20, 120, 150, 20, hWnd, NULL, hInst, NULL);
but when I type text inside of it I can't type more text than the width of the EDIT control. When I reach the end it's like there's no more space and I get a beep. How can I make the text scroll in this situation?
You can give your edit control the WS_HSCROLL and/or WS_VSCROLL window styles. For instance:
HWND myText
= CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_VISIBLE | WS_HSCROLL | ES_LEFT | ES_MULTILINE,
20, 120, 150, 20, hWnd, NULL, hInst, NULL);
Alternately, as Matthew T. Staebler rightfully suggests, use ES_AUTOHSCROLL and/or ES_AUTOVSCROLL (note the ES_ prefix, as these are edit styles, not window styles).