WS_TABSTOP on WS_CHILD dialogs - c++

I'm working with simple dialogs. The dialog box is created from the resource file. When creating a dialog box WS_CHILD, everything works fine. I can easily switch between items(edit boxes and buttons) using the VK_TAB key. But when I try to change the type of dialog box to WS_POPUP, switching between the elements becomes impossible. Focus is stuck on the first element and when I push the VK_TAB key I get a system alert sound(like "ding"). Any suggestions?
Compiler : gcc 4.6.x
Resource example:
DIALOG_CLIENT_SETTINGS DIALOG 0, 0, 156, 132
STYLE WS_CHILD | WS_VISIBLE | DS_CONTROL // Tab key stucks when change to WS_POPUP
CAPTION "Settings"
FONT 8, "Ms Shell Dlg"
LANGUAGE LANG_NEUTRAL, 0
{
CONTROL "Account Settings", IDC_GROUPBOX_1, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 8, 4, 140, 50
CONTROL "Login:", IDC_STATIC_1, "STATIC", SS_RIGHT | WS_CHILD | WS_GROUP | WS_VISIBLE, 16, 20, 40, 8
CONTROL "Password:", IDC_STATIC_2, "STATIC", SS_RIGHT | WS_CHILD | WS_GROUP | WS_VISIBLE, 16, 36, 40, 8
EDITTEXT IDC_EDIT_1, 60, 18, 80, 12, ES_LEFT | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE, WS_EX_WINDOWEDGE
EDITTEXT IDC_EDIT_2, 60, 34, 80, 12, ES_LEFT | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE, WS_EX_WINDOWEDGE
CONTROL "Cancel", IDC_BUTTON_1, "BUTTON", BS_PUSHBUTTON | BS_VCENTER | BS_CENTER | WS_CHILD | WS_TABSTOP | WS_VISIBLE, 98, 112, 50, 14
CONTROL "Apply", IDC_BUTTON_2, "BUTTON", BS_PUSHBUTTON | BS_VCENTER | BS_CENTER | WS_CHILD | WS_TABSTOP | WS_VISIBLE, 42, 112, 50, 14
}

You need to use IsDialogMessage in your main message loop so that messages can be intercepted and processed correctly by the dialog. You don't explain how your message loop is implemented, and this will affect how you do this. One way is to code it directly:
while(GetMessage(&Msg, NULL, 0, 0))
{
if(!IsDialogMessage(hDialogWnd, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
If you use some framework, such as MFC, for your message loop, then you would intercept it by using an override of PreTranslateMessage, something like this:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
if(IsDialogMessage(pMsg))
return TRUE;
else
return CDialog::PreTranslateMessage(pMsg);
}

Related

C++ Create and Add items to listbox

Sorry for this noob question but i'm new to C++ (coming from C#). I have a list of items from an array that i want to display on a listbox (just do display - nothing else). Adding a control in c++ was a lot harder than i thought.
Here's what i have so far: I'm not sure how to proceed from here and how to get it to work. Thanks in advance.
// .rh file
#define IDC_LISTDIR 106
//in the .rc file
CONTROL "ListBox", IDC_LISTDIR, "listbox", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOHSCROLL | WS_GROUP, 8, 80, 200, 60
//main
SendMessage(HANDLE, LB_ADDSTRING, 0, (LPARAM)L"Add This Text to listbox");
Also, i'm getting this:
error C2275: 'HANDLE' : illegal use of this type as an expression
IDD_MAINWINDOW DIALOG 36, 54, 421, 252
EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE
CAPTION "Listbox Test"
FONT 9, "MS Sans Serif"
{
CONTROL "&OK", IDOK, "button", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 100, 5, 40, 14
CONTROL "&Cancel", IDCANCEL, "button", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 100, 30, 30, 14
CONTROL "CheckBox", IDC_YESNO, "button", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 9, 55, 77, 22
CONTROL "ListBox", IDC_LISTDIR, "listbox", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOHSCROLL | WS_GROUP, 8, 80, 200, 60
}
SendMessage() takes an HWND to send the message to. HANDLE is a type, not an HWND variable. You need the actual HWND of the ListBox at runtime. Use GetDlgItem() to get that, eg:
HWND hwndLB = GetDlgItem(hwndDlg, IDC_LISTDIR);
SendMessage(hwndLB, LB_ADDSTRING, 0, (LPARAM)L"Add This Text to listbox");
Where hwndDlg is the HWND of the window that the ListBox is a child of.

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.

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.

c++ edit box goes behind main window

i created a edit box but it doesn't show on the window. it shows if the window is not full screen. if it is full screen the edit box goes behind it. here is the function for the edit box
HWND editbox=CreateWindowA("EDIT", NULL,
WS_VISIBLE | WS_EX_TOPMOST | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
hWnd,
(HMENU)5, hInstance, NULL);
i don't know why it does that i set it to WS_EX_TOPMOST and it still goes behind it. i used directx 9 to make my program in full screen
All WS_EX_** styles should be passed as the first argument of CreateWindowEx, not the third of CreateWindow. This probably causes the problem. Use CreateWindowExA instead.
All the arguments in CreateWindowEx remain the same, there's just one additional parameter at the beginning.
HWND editbox=CreateWindowExA(WS_EX_TOPMOST, "EDIT", NULL,
WS_VISIBLE | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
hWnd,
(HMENU)5, hInstance, NULL);
EDIT: I know what was wrong. You forgot the WS_CHILD style in the third argument. It is needed so Windows knows that this is a child window.
HWND editbox=CreateWindowA("EDIT", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
hWnd,
(HMENU)5, hInstance, NULL);
HWND editbox=CreateWindowA("EDIT", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
87, 81, 150, 17,
hWnd,
(HMENU)5, hInstance, NULL);
WS_CHILD is required if you want to display the new control atop a window...

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.