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

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.

Related

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?

Moving a child control to top

How can i move a control to top of the other when they have overlap together in windows API.
For example i create 2 buttons b1 and b2
HWND b1 = CreateWindow(L"BUTTON", L"button1", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
100, 100, 200, 50, my_Window_handle, (HMENU)100, NULL, NULL);
HWND b2 = CreateWindow(L"BUTTON", L"button2", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
50, 100, 250, 50, my_Window_handle, (HMENU)101, NULL, NULL);
I want to move b1 to top of the b2 or any control.
I used the function SetWindowPos as
SetWindowPos(b1, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
but id does not work correctly.
You don't want the child window to be top most, you want it to be at the top of the z-order. Like this:
SetWindowPos(b1, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
The documentation says for HWND_TOP:
Places the window at the top of the Z order.
Topmost will not work here because the child window must stay at the same z-order as its parent and SetWindowPos with HWND_TOPMOST as Hwnd_InsertAfter will try to change it. Only thing you need here is WS_CLIPSIBLINGS and then b1 will remain on top of b2.
b1 = CreateWindow(L"BUTTON", L"button1", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
100, 100, 200, 50, hWnd, (HMENU)100, NULL, NULL);
b2 = CreateWindow(L"BUTTON", L"button2", WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, 50, 100, 250, 50, hWnd, (HMENU)101, NULL, NULL);
As well as setting the z-order, you need to set the WS_CLIPSIBLINGS style on the controls if they overlap, to stop them drawing over the top of each other.

Up-Down control doesn't show its position in its buddy window

I created an up-down control by the following code.
HWND hEdit, hUpDown;
hEdit = CreateWindowExW(WS_EX_CLIENTEDGE,
L"EDIT",
Content.c_str(),
ES_LEFT | WS_VISIBLE | WS_CHILD,
600,
260,
100,
25,
hWndParent,
NULL,
hInstance,
NULL);
INITCOMMONCONTROLSEX iccx;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccx.dwICC = ICC_UPDOWN_CLASS;
InitCommonControlsEx(&iccx);
hUpDown = CreateWindowExW( 0,
UPDOWN_CLASSW,
L"",
UDS_ARROWKEYS | UDS_ALIGNRIGHT | WS_VISIBLE | WS_CHILD,
0,
0,
0,
0,
hWndParent,
NULL,
hInstance,
NULL);
SendMessageW(hUpDown, UDM_SETBUDDY, (WPARAM) hEdit, (LPARAM) NULL);
SendMessageW(hUpDown, UDM_SETRANGE32, (WPARAM) 0, (LPARAM) 100);
Sleep(5000);
SendMessageW(hUpDown, UDM_SETPOS32, (WPARAM) NULL, (LPARAM) 20);
Sleep(5000);
SendMessageW(hUpDown, UDM_SETPOS32, (WPARAM) NULL, (LPARAM) 60);
I checked the return values of the SendMessageW() functions. They terminate successfully by returning the previous position value as documented.
The created up-down control looks normal:
The problem is, sending the UDM_SETPOS32 message, clicking the up and down arrows and pressing the up and down keys on the keyboard have no effect. I can't change the contents of the edit control (the buddy window of the up-down control) without directly typing something into it. It just stays empty.
I am able to type anything in it manually by using keyboard:
How do I change the position/value of this up-down control by pressing keyboard arrow keys, by clicking the arrows in the GUI and by sending UDM_SETPOS32 in the code? What am I missing in my code?
Use the style UDS_SETBUDDYINT to the up-down control while creating it.
From MSDN documentation:
UDS_SETBUDDYINT
Causes the up-down control to set the text of the buddy window (using the WM_SETTEXT message) when the position changes. The text consists of the position formatted as a decimal or hexadecimal string.
Change the creation code of the up-down control like this by adding the UDS_SETBUDDYINT style:
hUpDown = CreateWindowExW( 0,
UPDOWN_CLASSW,
L"",
UDS_SETBUDDYINT | UDS_ARROWKEYS | UDS_ALIGNRIGHT | WS_VISIBLE | WS_CHILD,
0,
0,
0,
0,
hWndParent,
NULL,
hInstance,
NULL);

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).

Capturing keyboard input on a List View control, 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.