Tracking tooltip in Win32 C++ - c++

In a Win32 / C++ app, running under 64-bit Windows 7, using Visual Studio 16.7.7, I want to implement tracking tooltips in the main (and only) window. Following the examples in Microsoft SDK documentation, the tracking seems to work, but the tooltip window itself does not appear.
I have verified, using the debugger, that the tooltip is activated and deactivated, that the expected mouse tracking is occurring, that the screen coordinates in the TTM_TRACKPOSITION message are correct, and the text is OK. The app is Unicode, and I have checked that the structures are the Unicode versions, and common controls are initialized, and that the current version of the common controls library is linked. The tooltip window has the WS_EX_TOPMOST and WS_EX_TOOLWINDOW extended styles, per Spy++.
What changes are needed to make the tooltip show?
Here is the code I am using:
Global variables:
HINSTANCE hInst;
HWND hWnd;
HWND hwndTT;
WCHAR ttText[12];
TOOLINFO toolTipInfo;
BOOL trackingMouse;
Initialization:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
// Set up for mouse tracking (tooltips)
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_BAR_CLASSES;
BOOL ok=InitCommonControlsEx(&icc);
trackingMouse = FALSE;//
WCHAR nullString[15] = { L"After create" };
hwndTT = CreateTrackingToolTip(0 /*toolID*/, hWnd, nullString);
...
HWND CreateTrackingToolTip(int toolID, HWND hWndParent, WCHAR* pText)
{
// Create a tooltip.
HWND h = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWndParent, NULL, hInst, NULL);
if(!h)
{
return NULL;
}
// Set up the tool information. In this case, the "tool" is the entire parent window.
memset(&toolTipInfo, 0, sizeof(TOOLINFO));
toolTipInfo.cbSize = sizeof(TOOLINFO);
toolTipInfo.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
toolTipInfo.hwnd = hWndParent;
toolTipInfo.hinst = hInst;
toolTipInfo.lpszText = pText;
toolTipInfo.uId = (UINT_PTR)hWndParent;
GetClientRect(hWndParent, &toolTipInfo.rect);
// Associate the tooltip with the tool window.
SendMessage(h, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&toolTipInfo);
return h;
}
Window procedure:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MOUSELEAVE: // The mouse pointer has left our window. Deactivate the tooltip.
SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)FALSE, (LPARAM)&toolTipInfo);
trackingMouse = FALSE;
TRACE(L"\nDeactivate tooltip");
return FALSE;
case WM_MOUSEMOVE:
static int oldX, oldY;
int newX, newY;
if(!trackingMouse) // The mouse has just entered the window.
{ // Request notification when the mouse leaves.
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
tme.hwndTrack = hWnd;
tme.dwFlags = TME_LEAVE;
BOOL ok=TrackMouseEvent(&tme);
// Activate the tooltip.
SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&toolTipInfo);
trackingMouse = TRUE;
TRACE(L"\nActivate tooltip");
}
newX = GET_X_LPARAM(lParam); newY = GET_Y_LPARAM(lParam);
// Make sure the mouse has actually moved. The presence of the tooltip
// causes Windows to send the message continuously.
if((newX != oldX) || (newY != oldY))
{
oldX = newX; oldY = newY;
// Update the text.
swprintf_s(ttText, ARRAYSIZE(ttText), L"%d, %d", newX, newY);
toolTipInfo.lpszText = ttText;
SendMessage(hwndTT, TTM_SETTOOLINFO, 0, (LPARAM)&toolTipInfo);
// Position the tooltip. The coordinates are adjusted so that the tooltip does not overlap the mouse pointer.
POINT pt = { newX, newY };
ClientToScreen(hWnd, &pt);
SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(pt.x + 10, pt.y - 20));
}
return FALSE;
...

The following line is required:
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
Refer to "Using Manifests or Directives to Ensure That Visual Styles Can Be Applied to Applications" for more detailed information.

Related

Weird cursor behavior: Almost always the resize cursor. (win32 api)

I'm working with the win32 API, and am using it to make a window. This window works, but when I open it, the cursor is a loading cursor, and every time I bring my cursor to the edge to resize it, the cursor gets 'stuck' as that resizing cursor, it doesn't go back to normal. Here's a video to explain what I'm talking about:
Here's the reproducible example (compile with g++ reproducible_example.cpp -mwindows -O3 -o reproducible_example.exe):
#undef UNICODE
#undef _UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
bool isRunning = true;
void *buffer; // buffer memory
BITMAPINFO bmi; // bit map information, needed for rendering
int width, height; // main window's width and height
LRESULT __stdcall WindowProc(HWND, UINT, WPARAM, LPARAM);
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR pCmdLine, int nCmdShow) {
LPCSTR CLASS_NAME = "Class Name";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowExA(0, // Optional window styles.
"Class Name", // Window class
"Window", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
return 0;
ShowWindow(hwnd, nCmdShow);
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
// Run the message loop.
HDC hdc = GetDC(hwnd);
while (isRunning) {
MSG msg;
if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
StretchDIBits(hdc, 0, 0, width, height, 0, 0, width, height, buffer, &bmi,
DIB_RGB_COLORS, SRCCOPY);
}
ReleaseDC(hwnd, hdc);
return 0;
}
LRESULT __stdcall WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
isRunning = false;
return 0;
case WM_SIZE: {
// Calculate window height and width
width = LOWORD(lParam);
height = HIWORD(lParam);
if (buffer) // If memory already exists
// free it
VirtualFree(buffer, 0, MEM_RELEASE);
// Allocate buffer memory
buffer = VirtualAlloc(0, width * height * sizeof(unsigned int),
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height;
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Now, I know this isn't some weird windows bug and is definitely something with my code, because it doesn't happen in other apps which I open, and it also didn't happen when I made an equivalent window with SFML (probably because the windows api and SFML are entirely different things). Code for that window:
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(1280, 720), "Window");
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
window.close();
}
}
window.clear();
window.display();
}
}
I want the first window to act like the second window, but the cursor is the one discrepancy I can find. I've tried googling this, but to no avail. I followed a youtube tutorial series for the window I'm having problems with. Also, on downloading the tutorial's source code and removing some code which makes it full screen and hides the cursor, it has the same problem. How do I fix this? Thank you in advance.
Set wc.hCursor to something other than null. If it's null, the operating system will leave the cursor alone when it enters your window, and you're supposed to set it to the cursor you want.
Most likely you want the boring old arrow cursor. You can get that cursor by calling LoadCursor(NULL, IDC_ARROW).

Program window doesn't show up

I'm starting programming in C++ and want to start making applications with graphics and user interface.
I've watched many tutorials on the subject,
and have finished the first part of the tutorial
but the window refused to pop up, and I know that it's working because there are no errors,
and I can see it running in task manager.
Please help.
Hear is the code:
#include <Windows.h>
bool running = true;
LRESULT CALLBACK windows_callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
switch (uMsg) {
case WM_CLOSE:
case WM_DESTROY: {
running = false;
}break;
default: {
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
return result;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
//compile window
WNDCLASS window_class = {};
window_class.style = CS_HREDRAW | CS_VREDRAW;
window_class.lpszClassName = 0;
window_class.lpfnWndProc = windows_callback;
//register clases
RegisterClass(&window_class);
// create window
HWND window = CreateWindowA(0, "game stuff", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 720, 360, 0, 0, hInstance, 0); {
while (running) {
// input
// simulate
MSG mesage;
while (PeekMessage(&mesage, window, 0, 0, PM_REMOVE)) {
TranslateMessage(&mesage);
DispatchMessage(&mesage);
}
// render
}
};
}
window refused to pop up, and I know that it's working because there
are no errors, and I can see it running in task manager.
You don't check the error for RegisterClass and CreateWindowA functions calls.
Check the return value of RegisterClass() you will find that the return value is zero, that indicates failure. To get extended error information, call GetLastError.
CreateWindowA() also fails, the return value is NULL. To get extended error information, call GetLastError.
If you use ANSI version of these functions, change WNDCLASS to WNDCLASSA, RegisterClass to RegisterClassA.
You missed class name in both two functions. The following is an example based on your presented code to make the window show up. You can have a try.
CHAR clsName[] = "test";
WNDCLASSA window_class = {};
window_class.style = CS_HREDRAW | CS_VREDRAW;
window_class.lpszClassName = clsName;
window_class.lpfnWndProc = windows_callback;
//register clases
ATOM atom = RegisterClassA(&window_class);
if (0 == atom)
{
DWORD err = GetLastError();
return 0;
}
// create window
HWND window = CreateWindowA(clsName, "game stuff", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 720, 360, 0, 0, hInstance, 0);
if (NULL == window)
{
DWORD err = GetLastError();
return 0;
}
More references: "Your First Windows Program", "Unicode in the Windows API".
Update:
why does it have a Chinese name (window's name displays unexecpted)
For using above sample code to display window's name expected you can change project setting to "Use Multi-Byte Character Set" like this:
Or you can use UNICODE APIs (RegisterClassW and CreateWindowW) with project setting "Use Unicode Character Set".
Or you can use the macros like RegisterClassEx and CreateWindowEx, it will choose UNICODE or ASCII version API along with your project setting automatically.

Win32: Why is full-screen mode buggy?

Currently, I'm trying to make a simple Win32 application that switches back and forth between fullscreen and windowed mode. I'm using the Chromium way of doing this as a reference. I created a class to handle windows to make things simpler.
I expected this to work by toggling fullscreen when the F4 key was pressed. Unfortunately, the styles appear to be applied correctly, but the window doesn't resize or move to the correct area. It also snaps to the top left corner of the screen for a moment before it returns to its original position. For some reason, input for the window passes to the one below it when I toggle fullscreen. Then I have to go to Task Manager to kill the program because I can't close the window or application.
I've tried storing the styles of the HWND in a class variable at creation (it starts out in windowed mode) and using the value to create the necessary style for the fullscreen window and restoring the windowed mode window. I have also tried immediately getting the window styles with GetWindowLongPtr when the ToggleFullscreen function is called. Both of these do not work.
Here is my code:
WindowHandler.h
#include <Windows.h> // Win32 API
#ifndef WINDOWHANDLER
#define WINDOWHANDLER
class WindowHandler // WindowHandler
{
public:
WindowHandler(); // Constructor
void Destroy() { DestroyWindow(hwnd); } // Destroy the handler
void ToggleFullscreen(); // Toggle fullscreen
protected:
static LRESULT CALLBACK WindowProc // Window procedure
(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
HWND hwnd; // The window
// Everything involved in fullscreen
bool fullscreen = false; // Whether the window is fullscreen or not
RECT windowRect = {}; // The restored window size
long int windowStyles = 0; // The restored window styles
long int extendedWindowStyles = 0; // The restored window extended styles
};
#endif
WindowHandler.cpp
#include "WindowHandler.h" // Header file
WindowHandler::WindowHandler() // Constructor
{
WNDCLASS wndClass = {}; // The window information
wndClass.lpfnWndProc = WindowProc;
wndClass.hInstance = GetModuleHandle(nullptr);
wndClass.lpszClassName = L"FullscreenTest";
RegisterClass(&wndClass); // Register the window
hwnd = CreateWindowEx // Create the window and store a pointer to the handler for the procedure to use
(
0,
L"FullscreenTest",
L"Stack Overflow Repro",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
nullptr,
nullptr,
GetModuleHandle(nullptr),
this
);
if (hwnd == nullptr) Destroy(); // Destroy the handler if the window is invalid
else // Otherwise...
{
GetWindowRect(hwnd, &windowRect); // Store the window size
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE); // Store the window styles
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE); // Store the extended window styles
ShowWindow(hwnd, SW_SHOW); // Show the window
}
}
void WindowHandler::ToggleFullscreen() // Toggle fullscreen
{
if (!fullscreen) // If fullscreen is not enabled
{
MONITORINFO monitorInfo; // Get the monitor info
monitorInfo.cbSize = sizeof(monitorInfo);
GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &monitorInfo);
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyles & ~(WS_CAPTION | WS_THICKFRAME)); // Set the window styles
SetWindowLongPtr // Set the extended window styles
(
hwnd,
GWL_EXSTYLE,
extendedWindowStyles & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)
);
SetWindowPos // Resize, move, and refresh the window
(
hwnd,
nullptr,
monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.top,
monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED
);
fullscreen = true; // Indicate that fullscreen is on
}
else // Otherwise...
{
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyles); // Set the window styles
SetWindowLongPtr(hwnd, GWL_EXSTYLE, extendedWindowStyles); // Set the extended window styles
SetWindowPos // Resize, move, and refresh the window
(
hwnd,
nullptr,
windowRect.left,
windowRect.top,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED
);
fullscreen = false; // Indicate that fullscreen is off
}
}
LRESULT CALLBACK WindowHandler::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // Window procedure
{
WindowHandler* handlerPtr; // Pointer to the window handler
if (message == WM_CREATE) // If the window is being created...
{
CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam); // Get the pointer's container
handlerPtr = reinterpret_cast<WindowHandler*>(createStruct->lpCreateParams); // Get the pointer
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)handlerPtr); // Store the pointer
}
else handlerPtr = reinterpret_cast<WindowHandler*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); // Otherwise, get the pointer
if (handlerPtr) { // If the pointer is valid...
switch (message)
{
case WM_PAINT: // Paint the window
{
PAINTSTRUCT paintStruct;
HDC hdc = BeginPaint(hwnd, &paintStruct);
FillRect(hdc, &paintStruct.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &paintStruct);
}
return 0;
case WM_DESTROY: // Destroy the window
PostQuitMessage(0);
return 0;
case WM_KEYDOWN: // Process input
switch ((int)wParam)
{
case VK_ESCAPE: // Quit if the escape key is pressed
handlerPtr->Destroy();
break;
case VK_F4: // Toggle fullscreen if F4 is pressed
handlerPtr->ToggleFullscreen();
break;
}
return 0;
default: // Do the default action if the message was not processed
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
else return DefWindowProc(hwnd, message, wParam, lParam); // Do the default action if the pointer is not valid
}
main.cpp
#include "WindowHandler.h" // Window handler
int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) // Win32 main function
{
WindowHandler repro; // Create a window handler
MSG msg = {}; // Message structure
while (GetMessage(&msg, nullptr, 0, 0)) // Message loop
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Replace:
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
ShowWindow(hwnd, SW_SHOW); // Show the window
With:
ShowWindow(hwnd, SW_SHOW); // Show the window
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
The WS_VISIBLE style bit does not get set until after that first ShowWindow(SW_SHOW).

Listview C++ win32 API - Example Not Working

I am trying to create a listview in C++ with the win32 api, however the code supplied on mdsn is giving me an error.
HWND CreateListView (HWND hwndParent)
{
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
RECT rcClient; // The parent window's client area.
GetClientRect (hwndParent, &rcClient);
// Create the list-view window in report view with label editing enabled.
HWND hWndListView = CreateWindow(WC_LISTVIEW, //ERROR red line under create window
L"",
WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hwndParent,
(HMENU)IDM_CODE_SAMPLES, //ERROR IDM CODE SAMPLES undefined
g_hInst, //ERROR
NULL);
return (hWndListView);
}
This example is strait from mdsn and I have no idea why it is not working. I am getting IDM_CODE_SAMPLES Undefined, and something wrong with createwindow. Please help me to get this working it would be really helpful.
IDM_CODE_SAMPLES is the ID you want to assign to your control. You can either define the symbol to a numeric value, or use the numeric value directly (choose 100, for example). The ID is useful if you want to reference a particular control, although its HWND is equally useful as an ID.
g_hInst is presumably a global variable of type HMODULE, initialized from WinMain. If you don't want to use the global variable, you can call GetModuleHandle(nullptr) in its place, provided that you are compiling an .exe as opposed to a .dll.
You'll get a lot of helpful information when working through Intro to Win32 programming in C++.
I am now getting an error (1 unresolved externals)
We can find from InitCommonControlsEx function.
Ensures that the common control DLL (Comctl32.dll) is loaded, and
registers specific common control classes from the DLL.
Add:
#include <commctrl.h>
#pragma comment(lib,"Comctl32.lib")
Minimal code example:
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib,"Comctl32.lib")
#define IDM_CODE_SAMPLES 101
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND CreateListView(HWND hwndParent);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
CreateListView(hwnd);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
HWND CreateListView(HWND hwndParent)
{
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
RECT rcClient; // The parent window's client area.
GetClientRect(hwndParent, &rcClient);
// Create the list-view window in report view with label editing enabled.
HWND hWndListView = CreateWindow(WC_LISTVIEW, //ERROR red line under create window
L"",
WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hwndParent,
(HMENU)IDM_CODE_SAMPLES, //ERROR IDM CODE SAMPLES undefined
GetModuleHandle(nullptr), //ERROR
NULL);
return (hWndListView);
}
Just in case someone else is having issues around SysListView32:
#include <Ole2.h>
OleInitialize(NULL);
#include <commctrl.h>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "comctl32.lib")
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
BOOL bRet = InitCommonControlsEx(&InitCtrls);
...
For reference: fully working example with bells and whistles: https://github.com/jjYBdx4IL/Win32-List-View

Why is WinAPI not creating the window with the configured size?

I am fairly new to C++ coding so this could be a really easy fix. I have recently created a basic WinMain window. When I run the program from either the IDE or .exe file the application doesn't open at the proper size.
I can resize the window but I'm not sure why it isn't opening at that size set.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Function prototypes
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
bool CreateMainWindow(HINSTANCE, int);
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM);
// global variable
HINSTANCE hinst;
// Constants
const char CLASS_NAME[] = "WinMain";
const char APP_TITLE[] = "Hello World";
const char WINDOW_WIDTH = 400;
const char WINDOW_HEIGHT = 400;
//==================================
// Starting point for the windows application
// Parameters are
// hInstance. Handle to the current instance of the application
// hPrevInstance. Always NULL, obsolete parameter
// lpCmdLine. Pointer to null-terminated string of command arguements
// nCmdShow. Specifies how the window is to be shown
//=================================
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
MSG msg;
// Create thw window
if (!CreateMainWindow(hInstance, nCmdShow))
return false;
// Main message loop
int done = 0;
while (!done)
{
// PeekMessage is a non blocking message for Windows messages
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Look for quit message
if (msg.message == WM_QUIT)
done = 1;
// Decode and pass messages on to WinProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
// Window event callback function
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
//Tell windows to kill this program
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// Create the window, returns False on error
bool CreateMainWindow(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wcx;
HWND hwnd;
// Fill in the window class structure with parameters
// That describe the main window
wcx.cbSize = sizeof(wcx); // Size of the structure
wcx.style = CS_HREDRAW | CS_VREDRAW; // Redraw if the size changes
wcx.lpfnWndProc = WinProc; // Points to windows procedure
wcx.cbClsExtra = 0; // No extra class memory
wcx.cbWndExtra = 0; // No extra window memory
wcx.hInstance = hInstance;
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // Predifined arrow
// Background brush
wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcx.lpszMenuName = NULL; // Name of menu resource
wcx.lpszClassName = CLASS_NAME; // Name of window class
wcx.hIconSm = NULL;
// Register the window class
// RegisterClassEx return 0 on error
if (RegisterClassEx(&wcx) == 0) // if error
return false;
// Create Window
hwnd = CreateWindow(
CLASS_NAME, // Name of window class
APP_TITLE, // Title bar text
WS_OVERLAPPEDWINDOW, // Window style
CW_USEDEFAULT, // Default horizontal postion of window
CW_USEDEFAULT, // Default vertical postion of window
WINDOW_WIDTH, // Width of window
WINDOW_HEIGHT, // Height of window
(HWND) NULL, // No parent window
(HMENU) NULL, // No menu
hInstance, // Handle to application window
(LPVOID) NULL); // No window parameters
// If there was an error the window
if (!hwnd)
return false;
// Show the window
ShowWindow(hwnd, nCmdShow);
// Send a WM_PAINT message to the window procedure
UpdateWindow(hwnd);
return true;
}
Change the two constant definitions from char to int:
const int WINDOW_WIDTH = 400;
const int WINDOW_HEIGHT = 400;
Assuming a signed character is 8-bits then char x = 400 actually sets x to 16.