How do I create two different comboboxes with different strings of items? - c++

I have created a combo box having a list of items. How do I create another one with different strings of items? Can I in anyway change the hWnd because it seems the first already has the hWndCombobxes. Thus, when I apply it to the second, I get an error message, indicating that there is a duplicate value.
Below is the code I have. What function should I call else?
case WM_CREATE: {
HWND hWndComboBox = CreateWindow (TEXT("COMBOBOX"), TEXT (""),
CBS_DROPDOWN| CBS_HASSTRINGS | WS_VSCROLL| WS_VISIBLE | WS_CHILD ,
100, 150, 200, 150,
hwnd ,(HMENU) ID_COMBOBOX 1, NULL, NULL);
// ADD 2 ITEMS
SendMessage (
hWndComboBox,
(UINT) CB_ADDSTRING,
(WPARAM) 0, (LPARAM) TEXT ("Item 1"));
SendMessage (
hWndComboBox ,
(UINT) CB_ADDSTRING,
(WPARAM) 0, (LPARAM) TEXT ("Item 2"));
// SEND THE CB_SETCURSEL MESSAGE TO DISPLAY AN INITIAL ITEM IN SELECTION FIELD
SendMessage (hWndComboBox , LB_SETCURSEL , (WPARAM) 0, (LPARAM) 1);

// put this declaration somewhere up (or better move it to an include file)
#define ID_COMBOBOX_1 1001
#define ID_COMBOBOX_2 1002
// end defines
case WM_CREATE: {
// it is preferably to use SendDlgItemMessage instead of SendMessage
// this make things easier
// you will not need combobox's HWND, just ComboBox ID
TCHAR *Combo_1_Data[]={
TEXT("Item 1"),
TEXT("Item 2")
};
TCHAR *Combo_2_Data[]={
TEXT("Element 1"),
TEXT("Element 2")
};
int i;
// create two different ComboBoxs
CreateWindow (TEXT("COMBOBOX"), TEXT (""),
CBS_DROPDOWN| CBS_HASSTRINGS | WS_VSCROLL| WS_VISIBLE | WS_CHILD ,
100, 150, 200, 150,
hwnd ,(HMENU) ID_COMBOBOX_1, NULL, NULL);
CreateWindow (TEXT("COMBOBOX"), TEXT (""),
CBS_DROPDOWN| CBS_HASSTRINGS | WS_VSCROLL| WS_VISIBLE | WS_CHILD ,
208, 150, 200, 150,
hwnd ,(HMENU) ID_COMBOBOX_2, NULL, NULL);
// Fill first Combo with its Data
for( i = 0 ; i < (sizeof(Combo_1_Data) / sizeof(Combo_1_Data[0]) ) ; i++ ){
SendDlgItemMessage (hwnd,ID_COMBOBOX_1 ,CB_ADDSTRING, 0, (LPARAM) Combo_1_Data[i]);
}
SendDlgItemMessage (hwnd, ID_COMBOBOX_1 , LB_SETCURSEL , (WPARAM) 0, (LPARAM) 1);
// Fill second Combo with its Data
for( i = 0 ; i < (sizeof(Combo_2_Data) / sizeof(Combo_2_Data[0] )) ; i++ ){
SendDlgItemMessage (hwnd,ID_COMBOBOX_2 ,CB_ADDSTRING, 0, (LPARAM) Combo_2_Data[i]);
}
SendDlgItemMessage (hwnd, ID_COMBOBOX_2 , LB_SETCURSEL , (WPARAM) 0, (LPARAM) 1);

Copy and paste the other combobox. Do the same for the 'Send message' function. Then change the hWnd of the second Combobox to hWndListBox. Do the same to 'Send message'.
HWND hWndListBox = CreateWindow (TEXT("COMBOBOX"), TEXT (""),
CBS_DROPDOWN| CBS_HASSTRINGS | WS_VSCROLL| WS_VISIBLE | WS_CHILD ,
100, 70, 200, 90,
hwnd ,(HMENU) NULL, NULL, NULL);
HWND hWndComboBox = CreateWindow (TEXT("COMBOBOX"), TEXT (""),
CBS_DROPDOWN| CBS_HASSTRINGS | WS_VSCROLL| WS_VISIBLE | WS_CHILD ,
100, 150, 200, 100,
hwnd ,(HMENU) NULL, NULL, NULL);
SendMessage (
hWndComboBox ,
(UINT) CB_ADDSTRING,
(WPARAM) 0, (LPARAM) TEXT ("Item 2"));
SendMessage (
hWndListBox ,
(UINT) CB_ADDSTRING,
(WPARAM) 0, (LPARAM) TEXT ("Item 1"));
// SEND THE CB_SETCURSEL MESSAGE TO DISPLAY AN INITIAL ITEM IN SELECTION FIELD
SendMessage (hWndComboBox , CB_SETCURSEL , (WPARAM) 0, (LPARAM) 0);
SendMessage (hWndListBox , CB_SETCURSEL , (WPARAM) 0, (LPARAM) 0);

Related

Use radio buttons for switching different views in the main window

I have an application in Win32/C++ that has three buttons located in the left side of the main window. When clicking on one of them, a group of radiobuttons has to be displayed to allow the user to switch views among different submenus.
The code looks like this:
case WM_CREATE:
{
HWND hWndButton=CreateWindowEx(NULL,
"BUTTON",
"Inserting",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
10,
10,
100,
24,
hWnd,
(HMENU)INSERT_BUTTON,
GetModuleHandle(NULL),
NULL);
HWND hWndButton2=CreateWindowEx(NULL,
"BUTTON",
"Listing",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
10,
60,
100,
24,
hWnd,
(HMENU)LIST_BUTTON,
GetModuleHandle(NULL),
NULL);
HWND hWndButton3=CreateWindowEx(NULL,
"BUTTON",
"Consulting",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
10,
110,
100,
24,
hWnd,
(HMENU)SELECT_BUTTON,
GetModuleHandle(NULL),
NULL);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case INSERT_BUTTON:
{
HWND hGrpButtons=CreateWindowEx(WS_EX_WINDOWEDGE,
"BUTTON",
"Select a table:",
WS_VISIBLE | WS_CHILD| BS_GROUPBOX, // Styles
150,30,470,70,
hWnd,
NULL,
GetModuleHandle(NULL), NULL);
HWND hwndCB1 = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "TSector", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_GROUP,
160, 60, 80, 20, hWnd,(HMENU)CB1, GetModuleHandle(NULL), NULL);
HWND hwndCB2 = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "TSeccio", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON ,
250, 60, 80, 20, hWnd,(HMENU)CB2, GetModuleHandle(NULL), NULL);
HWND hwndCB3 = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "TActivitat", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,
340, 60, 80, 20, hWnd,(HMENU)CB3, GetModuleHandle(NULL), NULL);
HWND hwndCB4 = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "TClasse", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,
430, 60, 80, 20, hWnd,(HMENU)CB4, GetModuleHandle(NULL), NULL);
HWND hwndCB5 = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "TQuantitat", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,
520, 60, 85, 20, hWnd,(HMENU)CB5, GetModuleHandle(NULL), NULL);
switch(HIWORD(wParam))
{
case CB1:
//Do something
break;
}
}
break;
}
break;
Maybe the switch after creating the radiobuttons is not well implemented but anyway, when compiling, any of the menus that I want to display when clicking on each radiobuttons are not recognised: the compile error I'm retrieving says that I need to declare each menu.
It sounds weird to me because it works in other cases.
Any help would be much appreciated.
CB1 is the identifier of your control, if it is undeclared then just declare using the #define, like this:
#define CB1 1000
the identifier cannot be repeated with id of others controls.
a good way to create menus is to create all the submenus hidden, and when someone click in an option, you just show the submenu using the ShowWindow function.
to create a hidden submenu, just remove the WS_VISIBLE in the CreateWindowEx.
see this example:
// Opts
#define Fruits 1
#define Colors 2
// Fruits
#define Apple 5
#define Pineapple 6
// Colors
#define Red 10
#define Blue 11
void HideAll(HWND hwnd)
{
// Fruits
ShowWindow(GetDlgItem(hwnd, Apple), SW_HIDE);
ShowWindow(GetDlgItem(hwnd, Pineapple), SW_HIDE);
// Colors
ShowWindow(GetDlgItem(hwnd, Red), SW_HIDE);
ShowWindow(GetDlgItem(hwnd, Blue), SW_HIDE);
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
// Menus - All created visible
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Fruits", WS_VISIBLE | WS_CHILD,
10, 10, 80, 20, hwnd,(HMENU)Fruits, GetModuleHandle(NULL), NULL);
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Colors", WS_VISIBLE | WS_CHILD,
10, 40, 80, 20, hwnd,(HMENU)Colors, GetModuleHandle(NULL), NULL);
// Fruits - All created Invisible
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Apple", WS_CHILD,
100, 10, 80, 20, hwnd,(HMENU)Apple, GetModuleHandle(NULL), NULL);
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Pineapple", WS_CHILD,
100, 40, 80, 20, hwnd,(HMENU)Pineapple, GetModuleHandle(NULL), NULL);
// Colors - All created Invisible
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Red", WS_CHILD,
100, 10, 80, 20, hwnd,(HMENU)Red, GetModuleHandle(NULL), NULL);
CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Blue", WS_CHILD,
100, 40, 80, 20, hwnd,(HMENU)Blue, GetModuleHandle(NULL), NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case Fruits:
// Hide old
HideAll(hwnd);
// Show new
ShowWindow(GetDlgItem(hwnd, Apple), SW_SHOW);
ShowWindow(GetDlgItem(hwnd, Pineapple), SW_SHOW);
break;
case Colors:
// Hide old
HideAll(hwnd);
// Show new
ShowWindow(GetDlgItem(hwnd, Red), SW_SHOW);
ShowWindow(GetDlgItem(hwnd, Blue), SW_SHOW);
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
This is the result of the program:
and when someone click in fruits, it show the fruits suboptions:
and when someone click in colors, the ShowWindow hide the old suboptions and show new suboptions:

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

Wrong symbols in the buffer using GetWindowText

There is combo box with two items and button on the main window. Combobox:
HWND hCombo;
hCombo = CreateWindow(L"COMBOBOX", L"combobox",
WS_CHILD | WS_VISIBLE | CBS_SORT | CBS_DROPDOWNLIST,
10, 55, 232, 500, hWnd, 0, hInstance, 0);
const wchar_t *langEnglish = L"English";
const wchar_t *langRussian = L"Russian";
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)langEnglish);
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)langRussian);
SendMessage(hCombo, CB_SETCURSEL, 0, 0);
I am trying to get selected item text in the WndProc by clicking on the button:
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BUTTON_OK:
wchar_t buf[10];
hCombo = GetDlgItem(hWnd, IDC_COMBO);
GetDlgItemText(hCombo, IDC_COMBO, (LPWSTR)buf, 10);
MessageBox(hWnd, (LPCWSTR)buf, NULL, MB_OK);
break;
}
} break;
I am using breakpoint in the MSVS2010 to see buf variable. It contains chinese symbols!!! Message box shows empty message (With the title "Error"). I want to see english text. What is wrong?
This code
nIndex = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
SendMessage(hCombo, CB_GETLBTEXT, nIndex, (LPARAM)buf);
fills buf with the same chinese symbols
SOLUTION:
hCombo = CreateWindow(L"COMBOBOX", L"combobox",
WS_CHILD | WS_VISIBLE | CBS_SORT | CBS_DROPDOWNLIST,
10, 55, 232, 500, hWnd, (HMENU)IDC_COMBO, hInstance, 0);
In order to get currently selected item from CBS_DROPDOWNLIST styled combo box you need CB_GETCURSEL to get selection index and then CB_GETLBTEXT to get the string.

Appending text to an edit control running out of room?

So here is my problem, it works fine until it reaches a certain amount of data. I can't show a whole html file for example that is about 1MB in the window it gets cut off.
Window:
case WM_CREATE:
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_READONLY | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
0, 0, 100, 100, hWnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
if(hEdit == NULL)
MessageBox(hWnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
LogText(hEdit,logstring);
break;
Function:
void LogText(HWND hEdit, const char * logstring)
{
const char * logstring2="\r\n";
int iLength = GetWindowTextLength(hEdit);
SendMessage(hEdit, EM_SETSEL, iLength, iLength);
SendMessage(hEdit, EM_REPLACESEL, 0, (LPARAM) logstring);
SendMessage(hEdit, WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
int iLength2 = GetWindowTextLength(hEdit);
SendMessage(hEdit, EM_SETSEL, iLength2, iLength2);
SendMessage(hEdit, EM_REPLACESEL, 0, (LPARAM) logstring2);
SendMessage(hEdit, WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
}
Usage:
logstring="Test";
LogText(hEdit, logstring);
Like I said, it works perfect, except it stops working after its spit out an unknown amount of data which I've noticed is a very consistent number.
You can change the text limit of an edit box with the EM_SETLIMITTEXT message. Just define the upper limit before you attempt to assign text to the edit box.

Parent Window creation

I know it is a very simple question but i currently cant create a parent window...
My code:
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static HWND paste;
static HWND update_list;
/*HWND changeuser = CreateWindow(0, 0,
0,
0, 0, x, y,
0, (HMENU)changeuser2, 0, NULL); */
switch(msg)
{
case WM_CREATE:
meniu(hwnd);
CreateWindow(TEXT("static"), TEXT("\nSuckers online:"),
WS_VISIBLE | WS_CHILD | SS_CENTER,
0, 0, x, 55,
hwnd, (HMENU)delete, NULL, NULL);
connected = CreateWindow(TEXT("edit"), TEXT(""),
WS_VISIBLE | WS_CHILD | WS_VSCROLL| ES_MULTILINE ,
0, 60, x, 340,
hwnd, (HMENU)delete2, NULL, NULL);
CreateWindow(TEXT("static"), TEXT(""),
WS_VISIBLE | WS_CHILD | SS_CENTER|BS_PUSHBUTTON,
0, 405, x, 358,
hwnd, (HMENU) delete3, NULL, NULL);
paste = CreateWindow(TEXT("Edit"), TEXT("Paste the ip here"),
WS_VISIBLE | WS_CHILD | SS_CENTER,
x/2 - 60, 410, 120, 40,
hwnd, (HMENU) ip, NULL, NULL);
CreateWindow(TEXT("Button"), TEXT("Connect!"),
WS_VISIBLE | WS_CHILD | SS_CENTER | BS_PUSHBUTTON,
x/2 - 120, 450, 120, 40,
hwnd, (HMENU) connect2, NULL, NULL);
update_list = CreateWindow(TEXT("Button"), TEXT("Update the list!"),
WS_VISIBLE | WS_CHILD | SS_CENTER | BS_PUSHBUTTON,
x/2, 450, 120, 40,
hwnd, (HMENU) update, NULL, NULL);
_beginthread( lista, 0, (void*)(0) );//begin thread lista
break;
case WM_CTLCOLORSTATIC : {
HBRUSH br = CreateSolidBrush(RGB(80,67,77)); // change background color
SetTextColor((HDC)wParam,RGB(0,102,51)); //the controls text color
return (LRESULT) br;
}
case WM_COMMAND:
switch LOWORD(wParam)
{
case exit:
PostQuitMessage(0);
break;
case ip:
int nr;
nr = GetWindowTextLength(paste);
if (nr >= 17)
SetWindowText(paste, "");
break;//omor textul, ca sa pot sa fac paste
case connect2:
GetWindowText(paste,adresa,16);
_beginthread( start, 0, (void*)(0) ); //as\ici se face conexiunea principala
//DestroyWindow(hwnd);
MessageBox(0,"Connected with the user","Ok",0);
break;
case update:
exit2 = true;
Sleep(100);
SetWindowText(connected,"");
_beginthread( lista, 0, (void*)(0) );//begin thread lista
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
I want the other windows created to be the child of the changeuser window...
I just cant make it happen...
Any help will be appreciated!
To change the window of a parent, use SetParent().
But i would think about the structure - if you need to change the parent of one or more windows in a normal dialog setting, it is likely these windows should have a different parent.
In your case there is a problem in your handling of window messages though:
If your message handler receives WM_DESTROY you call PostQuitMessage(), which probably results in your application closing.
There are two ways you can handle that:
use different window processes for your main dialog and child dialogs (preferably)
or use the hwnd parameter to decide wether you call PostQuitMessage()
You can't 'replace' a window. If you need to tear down and replace your main window, delete it and make a new one. Windows only get the parent flag when they have children, not because you tell them to.