Placeholder text in a Win32 Edit control - c

I am using the Win32 API. I have this code that creates an edit control:
CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_CHILD, 100, 100, 200, 20, hand, NULL, NULL, NULL);
How do I put placeholder text inside of this edit box?

You can use SendMessage with EM_SETCUEBANNER:
HWND editCtlHandle = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_CHILD | WS_BORDER, 100, 100, 200, 20, hWnd, NULL, hInstance, NULL);
WCHAR placeholderText[] = L"Enter here";
SendMessage(editCtlHandle, EM_SETCUEBANNER, FALSE, (LPARAM)placeholderText);
Or use Edit_SetCueBannerText macro:
Edit_SetCueBannerText(editCtlHandle, placeholderText);
The result will like this:

Related

How do I make a tab control with children elements?

I'm learning WINAPI, I read there's no children control in the sense a C#'s TabControl control does, so you have to create elements and show/hide by yourself. I read it may be done by drawing a dialog box inside tab page's area so I went to create a borderless dialog box being tab control's child, to make it have effect like C#'s. But I still couldn't make it. My dialog box is floating rather being tab control's child. I don't know to make it inside the tab page, I've tried setting the hWndParent to tab control's HWND and WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT flags in dwExStyle but still is floating over the tab control. Different approaches to solve this are welcome. I'm creating the tab control like this:
void AddTabControl(HWND hwnd)
{
hTab = CreateWindowW(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
0, 30, 250, 250,
hwnd,
(HMENU) 9,
NULL,
NULL);
InsertTabItem(hTab, 10, L"A");
InsertTabItem(hTab, 11, L"B");
}
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text)
{
TCITEMW tci = {0};
tci.mask = TCIF_TEXT;
tci.pszText = text;
tci.cchTextMax = lstrlenW(text);
if(SendMessage(tabHwnd, TCM_INSERTITEMW, id, (LPARAM) &tci) == -1) {
MessageBox(NULL,
L"couldn't create the new tab page",
L"tab errror",
MB_OK | MB_ICONERROR);
}
}
And the dialog box like this:
void CreateDialogBox(HWND hwnd)
{
CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT, // WS_EX_TOOLWINDOW to hide window from ALT+TAB
L"DialogClass", L"Dialog Box",
WS_VISIBLE | WS_POPUP | WS_SYSMENU,
100, 100, 400, 150,
hTab, NULL, ghInstance, NULL
);
}
the result is:
the expected result (made from C#, just for example, ignore the color differences, I'll fix this later):
here's the full code:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#define UNICODE
#include <windows.h>
#include <Commctrl.h>
#include <strsafe.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
void CreateDialogBox(HWND);
void RegisterDialogClass(HWND);
void AddTabControl(HWND hwnd);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
HINSTANCE ghInstance;
HWND mainWindow;
HWND hTab;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
HWND hwnd;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 500, 350, NULL, NULL, hInstance, NULL);
mainWindow = hwnd;
ghInstance = hInstance;
while( GetMessage(&msg, NULL, 0, 0)) {
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
RegisterDialogClass(hwnd);
AddTabControl(hwnd);
CreateDialogBox(hwnd);
break;
case WM_COMMAND:
CreateDialogBox(hwnd);
break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg) {
case WM_CREATE:
CreateWindowW(L"button", L"A",
WS_VISIBLE | WS_CHILD ,
50, 50, 80, 25, hwnd, (HMENU) 1, NULL, NULL);
CreateWindowW(L"button", L"B",
WS_VISIBLE | WS_CHILD ,
150, 50, 80, 25, hwnd, (HMENU) 2, NULL, NULL);
CreateWindowW(L"button", L"C",
WS_VISIBLE | WS_CHILD ,
250, 50, 80, 25, hwnd, (HMENU) 3, NULL, NULL);
break;
case WM_COMMAND:
DestroyWindow(hwnd);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
}
return (DefWindowProcW(hwnd, msg, wParam, lParam));
}
void RegisterDialogClass(HWND hwnd)
{
WNDCLASSEXW wc = {0};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpfnWndProc = (WNDPROC) DialogProc;
wc.hInstance = ghInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpszClassName = L"DialogClass";
RegisterClassExW(&wc);
}
void CreateDialogBox(HWND hwnd)
{
CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT, // WS_EX_TOOLWINDOW to hide window from ALT+TAB
L"DialogClass", L"Dialog Box",
WS_VISIBLE | WS_POPUP | WS_SYSMENU,
100, 100, 400, 150,
hTab, NULL, ghInstance, NULL
);
}
void AddTabControl(HWND hwnd)
{
hTab = CreateWindowW(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
0, 30, 250, 250,
hwnd,
(HMENU) 9,
NULL,
NULL);
InsertTabItem(hTab, 10, L"A");
InsertTabItem(hTab, 11, L"B");
}
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text)
{
TCITEMW tci = {0};
tci.mask = TCIF_TEXT;
tci.pszText = text;
tci.cchTextMax = lstrlenW(text);
if(SendMessage(tabHwnd, TCM_INSERTITEMW, id, (LPARAM) &tci) == -1) {
MessageBox(NULL,
L"couldn't create the new tab page",
L"tab errror",
MB_OK | MB_ICONERROR);
}
}
When you created the dialog box control, you lacked the WS_CHILD style and added the WS_POPUP style, which caused the dialog box you generated to float.
You only need to modify it to the WS_CHILD style, and appropriately modify the size of the control to achieve your desired effect.
void CreateDialogBox(HWND hwnd)
{
CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT, // WS_EX_TOOLWINDOW to hide window from ALT+TAB
L"DialogClass", L"Dialog Box",
WS_VISIBLE | WS_SYSMENU | WS_CHILD ,
10, 30, 350, 150,
hTab, NULL, ghInstance, NULL
);
}
void AddTabControl(HWND hwnd)
{
hTab = CreateWindowW(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
10, 30, 400, 250,
hwnd,
(HMENU)9,
NULL,
NULL);
InsertTabItem(hTab, 10, L"A");
InsertTabItem(hTab, 11, L"B");
}
It works like this:

Elements in tabs WinAPI

How can I add some elements(window) in my tab?
Use these:
INITCOMMONCONTROLSEX icex;
TCITEMW tie;
WM_CREATE:
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
Tab = CreateWindowW(WC_TABCONTROLW, NULL, WS_CHILD | WS_VISIBLE,
0, 0, 200, 150, hwnd, (HMENU)ID_TABCTRL, NULL, NULL);
CreateWindowW(WC_BUTTONW, L"Add", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
250, 50, 100, 25, hwnd, (HMENU)BTN_ADD, NULL, NULL);
In BTN_ADD I make two tabs.
case BTN_ADD: {
tie.mask = TCIF_TEXT;
tie.pszText = (LPWSTR)L"TAB1";
SendMessageW(Tab, TCM_GETITEMCOUNT, 0, 0);
SendMessageW(Tab, TCM_INSERTITEMW, 1, (LPARAM)(LPTCITEM)&tie);
tie.mask = TCIF_TEXT;
tie.pszText = (LPWSTR)L"TAB2";
SendMessageW(Tab, TCM_GETITEMCOUNT, 0, 0);
SendMessageW(Tab, TCM_INSERTITEMW, 2, (LPARAM)(LPTCITEM)&tie);
SendMessageW(Tab, TCM_GETITEMCOUNT, 0, 0);
//Add item in tab
CreateWindowW(WC_BUTTONW, L"BTN", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
50, 50, 30, 30, Tab, NULL, NULL, NULL);
break;
}
But this button added in hwnd (main), and when I open other tab, I continue to see this button. I need add content in a certain tab.
First tab
Second tab
I solved a problem. Understand, that need use a MoveWindow function. These tabs isn't content, but content attachment to window (Tab). I just created Tab via:
Tab = CreateWindowW(WC_TABCONTROLW, NULL, WS_CHILD | WS_VISIBLE,
0, 0, TAB_WEIGHT, TAB_HEIGHT,
hwnd, (HMENU)ID_TABCTRL, NULL, NULL);
Then I put down a few window (ListBox) on the Tab (which window).
ListBoxProcesses = CreateWindowEx(WS_EX_CLIENTEDGE, L"ListBox", NULL,
WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_WANTKEYBOARDINPUT,
0, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100,
Tab, (HMENU)ID_LIST, NULL, NULL);
ListBoxModules = CreateWindowEx(WS_EX_CLIENTEDGE, L"ListBox", NULL,
WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_WANTKEYBOARDINPUT,
TAB_WEIGHT, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100,
Tab, (HMENU)ID_LIST, NULL, NULL);
But there is one feature. First window (ListBoxProcesses) has a horizontal position 0. But second window (ListBoxModules) has TAB_WEIGHT. After I choose other tab, I call a MoveWindow function and its shifts my content.
Btw, yes, I understand that need use WM_NOTIFY message which contains this:
switch (wParam)
{
case ID_TABCTRL: {
switch (SendMessageW(Tab, TCM_GETCURFOCUS, 0, 0))
{
case FIRST_PAGE: {
MoveWindow(ListBoxProcesses, 0, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100, TRUE);
MoveWindow(ListBoxModules, TAB_WEIGHT, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100, TRUE);
break;
}
case SECOND_PAGE: {
MoveWindow(ListBoxProcesses, -TAB_WEIGHT, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100, TRUE);
MoveWindow(ListBoxModules, 0, 50, TAB_WEIGHT - 20, TAB_HEIGHT - 100, TRUE);
break;
}
default:
break;
}
break;
}
default:
break;
}
First tab
Second tab

Tooltip control doesn't appear but is created

I am attempting to get a tooltip to appear over a Static control. I've followed the MSDN example almost word for word but the tooltip doesn't appear. Maybe I need to initialise a specific common control prior to creating a tooltip? Right now I initialise ICC_STANDARD_CLASSES and ICC_COOL_CLASSES.
Any idea why the tooltip doesn't appear?
case WM_CREATE:
{
INITCOMMONCONTROLSEX iccx;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_COOL_CLASSES;
InitCommonControlsEx(&iccx);
HWND hwndTool = CreateWindowEx(0, _T("Static"), _T("Abc"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 10, 100, 100, hWnd, (HMENU)50001, hInst, NULL);
HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, NULL,
hInst, NULL);
// Associate the tooltip with the tool.
LPTSTR pszText = _T("Def");
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hWnd;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hwndTool;
toolInfo.lpszText = pszText;
output(_T("Is null: %d\n"), hwndTip == NULL); // output = Is null: 0
output(_T("Send res: %d\n"), SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo)); // output = Send res: 0
}
break;

I cannot press enter on the button

This is my first program in C using WINAPI.
When I click the button with my mouse, everything is OK, but I cannot press the button with Enter. On the other hand, Space is working.
I'm guessing that the problem is in "IsDialogMessage" but I cannot solve it.
This is my code in WinMain:
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage(&msg, NULL, 0, 0))
{
if (IsDialogMessage(hwnd, &msg) && msg.wParam != VK_RETURN )
{
/* Already handled by dialog manager */
}
else {
TranslateMessage(&msg); /* Translate virtual-key messages into character messages */
DispatchMessage(&msg); /* Send message to WindowProcedure */
}
}
and this is my LRESULT CALLBACK code :
LRESULT CALLBACK wg_WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND cb_handle = 0;
static HWND g_hButtonLogin = 0;
static HWND g_hButtonConfig = 0;
static HWND hEditLogin = 0;
static HWND hLabelLogin = 0;
static HWND hEditPass = 0;
static HWND hLabelPass = 0;
static int pozycja_3 = 0;
struct sesslist slist;
switch (message) /* handle the messages */
{
case WM_CREATE:
{
// LOGIN
hLabelLogin = CreateWindowEx(0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 20, 40, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
hEditLogin = CreateWindowEx(0, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 80, 20, 150, 25,
hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
// PASSWORD
hLabelPass = CreateWindowEx(0, "STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 50, 40, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
hEditPass = CreateWindowEx(0, "EDIT", NULL, ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 80, 50, 150, 25,
hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
SetWindowText(hLabelLogin, "Login:");
SetWindowText(hLabelPass, "Hasło:");
// COMBOBOX
cb_handle = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST | WS_TABSTOP, 80, 80, 150, 25 * 4, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
get_sesslist(&slist, TRUE);
// MessageBox(hwnd, slist.sessions[1] , "yyyyy", 0);
int a = 1;
while (slist.sessions[a] != NULL)
{
SendMessage(cb_handle, CB_ADDSTRING, 0, slist.sessions[a]);
a++;
}
SendMessage(cb_handle, CB_SETCURSEL, 3, (LPARAM)"4");
/*SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"MFG1");
SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"MFG2");
pozycja_3 = SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"3");
SendMessage(cb_handle, CB_ADDSTRING, 0, (LPARAM)"4");
SendMessage(cb_handle, CB_SETCURSEL, 0, (LPARAM)"4");*/
g_hButtonConfig = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "*", WS_CHILD | WS_VISIBLE,
260, 20, 20, 20, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
Then I Create Button "Zaloguj"
g_hButtonLogin = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "Zaloguj", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
20, 120, 250, 30, hwnd, NULL , ((LPCREATESTRUCT)lParam)->hInstance, ((LPCREATESTRUCT)lParam)->hInstance ) ;
CenterWindow(hwnd);
SetFocus(hEditLogin);
// wg_hDlgCurrent = hEditLogin;
}
break;
case WM_COMMAND:
{
if ((HWND)lParam == g_hButtonConfig)
{
do_config();
}
if ((HWND)lParam == g_hButtonLogin || (HWND)wParam == g_hButtonLogin)
{
if (1 == 1)
{
int idx_row;
char *strText[256];
idx_row = SendMessage(cb_handle, CB_GETCURSEL, 0, 0);
SendMessage(cb_handle, CB_GETLBTEXT, idx_row, (LPARAM)strText);
wg_selected_sess = strText;
DestroyWindow(hwnd);
}
}
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;
}
When I hit the Enter key on the "zaloguj" button, nothing happens.

Win32 (GDI) - Set Opacity of STATIC Control

I'm using C - (NO MFC or GDI+) :-)
What I want is to set the opacity of my child window to let say 100 (my child window is a STATIC control). I was wondering if this is even possible and if so can someone please point me to the right direction on how to do it.
Here is my setup:
I create my Parent window as follow:
HWND hWnd;
WNDCLASS wndCls_s;
wndCls_s.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndCls_s.lpfnWndProc = MainWndProc;
wndCls_s.cbClsExtra = 0;
wndCls_s.cbWndExtra = 0;
wndCls_s.hInstance = hInstance;
wndCls_s.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BSN_64));
wndCls_s.hCursor = LoadCursor(NULL, IDC_ARROW);
wndCls_s.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
wndCls_s.lpszMenuName = NULL;
wndCls_s.lpszClassName = pszCName;
if (RegisterClass(&wndCls_s) == 0)
return EXIT_FAILURE;
/* Creating Window */
hWnd = CreateWindow(
pszCName, pszCName,
WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN,
0, 0, WND_WIDTH, WND_HEIGHT,
NULL, NULL, hInstance, NULL);
In my MainWndProc:
case WM_CREATE:
{
HWND hWndChild = CreateWindow(
L"STATIC", (LPCTSTR) NULL,
WS_CHILD | WS_VISIBLE,
10, 10, 110, 110,
hWnd, (HMENU) (int) 10000,
g_hInst, NULL);
}
break;
case WM_CTLCOLORSTATIC:
{
COLORREF dwColor;
dwColor = RGB(255, 0, 0);
hDC = (HDC) wParam;
//SetBkColor(hDC, dwColor);
SetBkMode(hDC, TRANSPARENT);
/*
This is not going to work for child window
SetWindowLong(
hWnd, GWL_EXSTYLE,
GetWindowLong((HWND)lParam, GWL_EXSTYLE) & ~WS_EX_LAYERED);
SetLayeredWindowAttributes(
(HWND)lParam, 0, 100, LWA_ALPHA);
RedrawWindow((HWND)lParam, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
*/
if (g_hBrushRed == NULL)
g_hBrushRed = CreateSolidBrush(dwColor);
}
return (INT_PTR)g_hBrushRed;
Why do you enable transparency with TRANSPARENT if you are going to return a valid brush for the background? You don't need SetBkMode and your red brush will be used by the control then.

Resources