Windows C++ API list view not showing - c++

I'm currently learning the Windows API for C++, and I'm trying to create a ListView control. I edited the source from MSDN documentation, but I'm stuck cause no list view actually shows in my window. When I create different controls they are shown without problems. I use this function to create the ListView.
HWND CreateListView(HWND hwndParent)
{
INITCOMMONCONTROLSEX icex;
icex.dwICC = ICC_LISTVIEW_CLASSES;
icex.dwSize = sizeof(icex);
if(InitCommonControlsEx(&icex) == FALSE) MessageBox(NULL,L"Initiation of common controls failed",L"Fail", MB_OK);
RECT rcClient;
GetClientRect(hwndParent, &rcClient);
HWND hWndListView = CreateWindow(WC_LISTVIEW,
L"",
WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hwndParent,
(HMENU)IDM_DATABAZA_LIST,
hInst,
NULL);
return (hWndListView);
}
The list view is created without problems,but it doesn't show in the window. What might be the issue here?

Add WS_VISIBLE flag:
HWND hWndListView = CreateWindow(WC_LISTVIEW, L"",
WS_VISIBLE|WS_CHILD|LVS_REPORT|LVS_EDITLABELS,...)
Or use ShowWindow(hWndListView, SW_SHOW) or SetWindowPos(hWndListView,...,SWP_NOZORDER|SWP_SHOWWINDOW);
And add error check
if (!hWndListView)
{
OutputDebugStringW(L"error\n");
return NULL;
}

Related

Adding Different Components in Tab Control Win32

I am creating a Windows desktop application using win32 api in visual studio 2019. I know there are many other options avialable to build UI like MFC, XAMAL and C#, but i needed to build it in win32. I have learnt some basics in win32 api but recently i was working on tabControll and there i got an issue or i missed some thing. I am creating two tabs and want to add different content withing them. My current code is working and creating the tabs but it is adding same content in both tabs. How should i define each tab's content differently.
void createTabView(HWND hWnd) {
RECT rcClient;
INITCOMMONCONTROLSEX icex;
static HWND hwndTab_1_1_1;
HWND hwndTab;
TCITEM tie;
int i;
TCHAR achTemp[256];
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
GetClientRect(hWnd, &rcClient);
hwndTab = CreateWindow(WC_TABCONTROL, L"",
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
0, 0, rcClient.right, rcClient.bottom,
hWnd, NULL, hInst, NULL);
// Add tabs for each day of the week.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 1, &tie);
tie.pszText = tabLBL2;
TabCtrl_InsertItem(hwndTab, 2, &tie);
SendMessage(hwndTab, WM_SETFONT,
reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
HWND hwndStatic = CreateWindow(WC_STATIC, L"",
WS_CHILD | WS_VISIBLE | WS_BORDER,
200, 200, 100, 100, // Position and dimensions; example only.
hwndTab, NULL, hInst, // g_hInst is the global instance handle
NULL);}
The tab control triggers the WM_NOTIFY signal when the tab page is switched, so as long as we process the WM_NOTIFY message, we can control the tab control message.
In the WM_NOTIFY message:
wParam: a control ID that identifies the WM_NOTIFY message sent.
lParam: a pointer to the NMHDR structure.
Therefore, we can determine the notification code sent by the Tab control in the WM_NOTIFY message processing program by judging the code value in the NMHDR structure.
We can use TCN_SELCHANGE to handle the operation when the Tab tab changes, and use TabCtrl_GetCurSel to get the index of the current tab and define the content of the current tab.
Here is the sample:
#include <Windows.h>
#include <commctrl.h>
LRESULT CALLBACK WndProc(HWND, UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("windows");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
}
hwnd = CreateWindow(szAppName,
TEXT("the hello program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while (GetMessageW(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
static HINSTANCE hInstance;
static HWND hwndTab = 0 , hwndStatic = 0;
TCITEM tie;
RECT rcClient;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
TCHAR tabLBL1[256];
GetClientRect(hwnd, &rcClient);
switch (message)
{
case WM_CREATE:
{
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hwndTab = CreateWindow(WC_TABCONTROL, "",
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
0, 0, rcClient.right, rcClient.bottom,
hwnd, NULL, hInstance, NULL);
// Add tabs for each day of the week.
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
wsprintf(tabLBL1, "tab1");
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 0, &tie);
wsprintf(tabLBL1, "tab2");
TabCtrl_InsertItem(hwndTab, 1, &tie);
SendMessage(hwndTab, WM_SETFONT,
reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
hwndStatic = CreateWindow(WC_STATIC, "",
WS_CHILD | WS_VISIBLE | WS_BORDER,
200, 200, 100, 100, // Position and dimensions; example only.
hwndTab, NULL, hInstance, // g_hInst is the global instance handle
NULL);
ShowWindow(hwndStatic,TRUE);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_NOTIFY:
if (((LPNMHDR)lParam)->code == TCN_SELCHANGE)
{
int tabID = TabCtrl_GetCurSel(hwndTab);
switch (tabID)
{
case 0:
ShowWindow(hwndStatic, TRUE);
break;
case 1:
ShowWindow(hwndStatic, FALSE);
break;
default:
break;
}
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
Not sure if this is the solution, but the iItem parameter to TabCtrl_InsertItem is zero-based. Try:
tie.pszText = tabLBL1;
TabCtrl_InsertItem(hwndTab, 0, &tie);
tie.pszText = tabLBL2;
TabCtrl_InsertItem(hwndTab, 1, &tie);
Also (and I'm not sure if this is relevant), you look like you intended to call InitCommonControlsEx in your code but fail to do so.

WinAPI - C++ - Add Hyperlink to Window

I was wondering, how can I add a hyperlink (A link to an online webpage) to my window. Do I use CreateWindow, WM_PAINT, etc? Please give me some advice. Thanks!
Edit:
Here's what i'm doing:
HWND CreateSysLink(HWND hDlg, HINSTANCE hInst, RECT rect){
return CreateWindowEx(0, WC_LINK,
"For more information, click here " \
"or <A ID=\"idInfo\">here</A>.",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
rect.left, rect.top, rect.right, rect.bottom,
hDlg, NULL, hInst, NULL);
}
I'm copying the hInstance from WinMain parameters to a global variable "globalhInstance" by running globalhInstance = hInstance; in WinMain. I'm also creating a global RECT called globalRect. Then on WM_CREATE, I'm calling GetWindowRect(hwnd, &globalRect); ("hwnd" is a parameter of WndProc). Finally, in a switch statement inside WM_COMMAND i'm calling CreateSysLink(hwnd, globalhInstance, globalRect);. But it just doesn't seem to work.
There's sample code from the MSDN page linked above:
HWND CreateSysLink(HWND hDlg, HINSTANCE hInst, RECT rect)
{
return CreateWindowExW(0, WC_LINK,
L"For more information, click here " \
L"or <A ID=\"idInfo\">here</A>.",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
rect.left, rect.top, rect.right, rect.bottom,
hDlg, NULL, hInst, NULL);
}

Adding Tooltips to Checkboxes in ATL-based C++ Dialogs

I'm attempting to add a set of tooltips to a set of checkboxes on a dialog inheriting from CAxDialogImpl, where CSG32GridViewControlDlg is my dialog's class.
Using the example code on MSDN as a base, I've added the following code:
void CSG32GridViewControlDlg::AddCheckboxTooltip(const int toolId, PTSTR tooltipText)
{
HWND hCheckbox = GetDlgItem(toolId);
char label1[501];
::GetWindowText(hCheckbox, label1, 500);
HINSTANCE hInstance = _AtlBaseModule.GetResourceInstance( ); // This bit I'm not sure about...
// Need to create the ToolTip first
HWND hWndToolTip = ::CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hCheckbox,
NULL,
hInstance, 0);
if (!hCheckbox || !hWndToolTip)
{
return;
}
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hCheckbox;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hWndToolTip;
toolInfo.lpszText = tooltipText;
LRESULT result = ::SendMessage(hWndToolTip, TTM_ADDTOOL, 0, (LPARAM) &toolInfo);
return hWndToolTip;
}
Debugging the code, I can see that the message gets sent, and the result comes back as "1", which would seem to suggest that everything's worked successfully. But when I mouseover the checkbox in question... no tooltip.
What could I do to check if the tooltip is successfully registered, and why might it not be appearing on Mouseover? Alternatively, is there a better way to approach this?
There are a few problems with your code. The starting point worth mentioning is obviosuly this: How to Create a Tooltip for a Control.
Parent window for the tooltip control should be the dialog, not the checkbox
uId member for the tool with TTF_IDISHWND flag needs to be the tool window, and not tooltip control window
This gives code:
HWND AddCheckboxTooltip(const int toolId, PTSTR tooltipText)
{
HWND hCheckbox = GetDlgItem(toolId);
// Need to create the ToolTip first
HWND hWndToolTip = ::CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
m_hWnd,
NULL,
_AtlBaseModule.GetModuleInstance(), 0);
if (!hCheckbox || !hWndToolTip)
return NULL;
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = hCheckbox;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)hCheckbox;
toolInfo.lpszText = tooltipText;
LRESULT result = ::SendMessage(hWndToolTip, TTM_ADDTOOL,
0, (LPARAM) &toolInfo);
return hWndToolTip;
}
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL& /*bHandled*/)
{
AddCheckboxTooltip(IDC_CHECK1, _T("Checkbox Tooltip Test"));
//...
Which runs as:

Win32: How to create a bordless popup window

Win32 API provides many styles for window creating and I'm looking for a style that can remove a one-pixel border from the window that I created with this code:
DWORD dwExtStyle = 0;
DWORD dwStyle = WS_POPUPWINDOW;
m_hWnd = CreateWindowEx(
dwExtStyle,
className,
windowName,
dwStyle,
300,
300,
100,
100,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(m_hWnd, SW_SHOW);
and I got the result:
What combination of flags can remove the black border from the window.
Just use WS_POPUP instead of WS_POPUPWINDOW.
The macro WS_POPUPWINDOW is actually a set of flags:
#define WS_POPUPWINDOW (WS_BORDER | WS_POPUP | WS_SYSMENU)
The WS_BORDER flag is the one responsible of your black square.

How should I create a child window in win32 while programming with C++?

i'm new to C++ as well as for windows programming..
i have created a window using msdn CreateWindow() function
which works correctly..now i would like to create a child window...the parent window should control the child window...
Any helps sample code regarding this .
Thanks in advance
Roughly speaking, in the handler for the parent, where you wish to create the child, you call CreateWindow, passing in the window for the parent as the hwndParent - probably, you also want to set certain styles on the child such as WS_CHILD. Your interaction with the child window then depends on the type of the window you created. Some windows (such as buttons) are designed to work as child windows, so they send a lot of notification messages, so you would set up your parent to listen for those notification messages.
I'd highly recommend having a read through Charles Petzold's "Programming Windows" if you can obtain a copy.
Otherwise, to answer your question, pass the parent window's handle as the parent when you create the child window (using either CreateWindow or CreateWindowEx):
HWND CreateWindowEx
(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent, /// pass the parent window handle here
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
..As 1800 Info has also stated, perhaps also set the WS_CHILD style (more oon Window Styles here). This is just the rudimentary plumbing, really..
Can you be a bit more specific when you say "control the child window..."?
It Is 2018 by now.. doing some retro work on this I found SetParent() to come out handy, to assure a child window remains inside the client region of the parent.. Before SetParent() the child need not be registered as a child. In CreateWindowEx the parent handle can be NULL at first. Style WS_CHILD is not needed, but WS_CLIPSIBLINGS comes out handy, it avoids flickering.
This is my code for creating a child window:
HWND hwnd = CreateWindowExA(0, "WindowOfDLL", ctitle, WS_SIZEBOX | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, hMenu, inj_hModule, NULL);
SetParent(hwnd, hwndparent);
ShowWindow(hwnd, SW_SHOWNORMAL);
I've seen no problems (yet) with threading in Win10. Each of below child windows is created in a DLL which manages the assembly. When a child window is created, the DLL adds a new member to the assembly and launches a thread, which will serve the child window and performs above code in its initialisation.
"could you post more of your code "
#BradB you're right.. our answers are all not very specific, this is old stuff it is difficult to put a complete frame in one post. Read the book RobS suggested I would say... and... take a look at Visual studio and more modern methods to design "child windows", like Winforms, WPF and Universal !
Here is some more of my legacy code, just the preparations, to let it be a CHILD window. The events etc you will have to fill in yourself..
BOOL RegisterDLLWindowClass(LPCWSTR s)
{
WNDCLASSEX wc;
wc.hInstance = NULL; // inj_hModule;
wc.lpszClassName = s;
wc.lpfnWndProc = DLLWindowProc;
wc.style = CS_DBLCLKS;
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
if (!RegisterClassEx(&wc))
return 0;
}
HMENU CreateDLLWindowMenu()
{
WriteLine("Create menu");
HMENU hMenu;
hMenu = CreateMenu();
HMENU hMenuPopup;
if (hMenu == NULL)
return FALSE;
hMenuPopup = CreatePopupMenu();
AppendMenu(hMenuPopup, MF_STRING, MYMENU_FILTERSOFF, TEXT("Off"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_CANNY, TEXT("Canny"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_SOBEL, TEXT("Sobel"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_THRESHOLD, TEXT("Threshold"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_DILATE, TEXT("Dilate"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_HARRIS, TEXT("Harris"));
CheckMenuItem(hMenuPopup, 0, MF_BYPOSITION | MF_CHECKED);
AppendMenuW(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup, TEXT("Filter"));
HMENU hMenuPopup2 = CreatePopupMenu();
AppendMenu(hMenuPopup2, MF_STRING, MYMENU_SAMPLE1, TEXT("Change parameter"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup2, TEXT("Test"));
return hMenu;
}
void WINAPI CreateAWindow(PassedToDLL *lpParam, DWORD dwStyle)
{
if (nInstances == 0) RegisterDLLWindowClass((LPCWSTR)L"WindowOfDLL");
HMENU hMenu = CreateDLLWindowMenu();
nInstances++;
CommonInfo[nInstances - 1] = lpParam;
int i = 20 + 4 * (rand() % 10);
lpParam->p = NewPanningStruct();
lpParam->hWndChild = CreateWindowEx(0, L"WindowOfDLL", lpParam->title,
dwStyle,
i, i, 800, 550, lpParam->hWndParent, hMenu, NULL, NULL);
if (wcslen(lpParam->filename) > 0)
{
LoadBitmapFromBMPFileW(lpParam->hWndChild, lpParam->filename, &(lpParam->hBmp),
&(lpParam->hPalette));
}
}