Passing an HINSTANCE to WNDCLASS using the main entry point - c

Consider the following code:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg;
HWND hwnd;
WNDCLASSW wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 350, 250, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
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_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
This creates a blank window, I want to reproduce this but using the main entry point instead of wWinMain.
The following code works, but it feels very hacky:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int main(int argc, HINSTANCE argv) {
MSG msg;
HWND hwnd;
WNDCLASSW wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszClassName = L"Window";
wc.hInstance = argv;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassW(&wc);
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 350, 250, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
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_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Is there a better way?

You can get the .exe HMODULE/HINSTANCE with GetModuleHandle(0).
The real Windows entrypoint has no parameters, the C run-time calls GetModuleHandle for you when using WinMain.

Related

Background image fails to get set for a window in WinApi

I am learning to how to set a background image for a window in C.
Here is my code:
#include <stdio.h>
#include <windows.h>
char* window_name = "Window";
char* window_title = "Window Title";
char* background_name = "test.bmp";
int window_width = 600;
int window_height = 400;
HBITMAP hbackground_image;
WNDCLASSEX wc;
HWND hwnd, hbackground;
MSG msg;
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_CREATE:
hbackground = CreateWindow("STATIC", "background", SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 300, 300, hwnd,
NULL, NULL, NULL);
hbackground_image = (HBITMAP)LoadImage(NULL, background_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SendMessage(hbackground, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbackground_image);
break;
default:
return DefWindowProc(hwnd, msg, wp, lp);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
wc.lpszClassName = window_name;
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Windows registration failure", NULL, MB_RETRYCANCEL);
return 1;
}
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, window_name, window_title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, window_width, window_height, NULL, NULL, hInstance, NULL);
// hwnd = CreateWindow("test", "test title", WS_OVERLAPPED | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, NULL, NULL); // This fails
if (!hwnd) // If fails
{
MessageBox(NULL, "Window creation failed :(", NULL, MB_RETRYCANCEL);
return 2;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
However, the background image doesn't get set even though there is a bitmap in the same folder as the .exe. I also tried different bitmaps from the internet, and one I made in paint. Any help would be appreciated.
This line is wrong:
wc.lpfnWndProc = DefWindowProc;
You are not seeing your background image because you are not using your WindowProcedure() with the window class, and thus it is never called to load/display the bitmap.
That line needs to be this instead:
wc.lpfnWndProc = WindowProcedure;
Also, when processing WM_CREATE, you are not return'ing any value, so the result is indeterminate, which is undefined behavior. You need to return 0; for that message:
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_CREATE:
...
return 0;
...
}
return DefWindowProc(hwnd, msg, wp, lp);
}

Win32 API Child window doesn't appear in parent's area

I am trying to write a simple app in Win32 API. The goal is to create a parent window with blue background and a child window (visible as a small red square) inside it.
I define a parent and child windows:
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMEPRACTICE3));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_GAMEPRACTICE3);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&wcex);
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE | WS_BORDER,
0,0, 400, 600, HWND_DESKTOP, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Child window
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = childClass;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hInstance = hInst;
wc.hbrBackground = CreateSolidBrush(RGB(255, 0, 0));
wc.lpfnWndProc = WndProc;
RegisterClassEx(&wc);
HWND hwnd_child = CreateWindow(childClass, NULL,
WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 32, 32,
hWnd, 0, hInst, 0);
ShowWindow(hwnd_child, nCmdShow);
UpdateWindow(hwnd_child);
When I launch the app I get the following output:
It seems that the child window is not displaying at all.
I tried to search similar problems on the Internet but none of the solutions worked for me so far.
Source code:
#include "stdafx.h"
#include "GamePractice3.h"
#define MAX_LOADSTRING 100
HINSTANCE hInst;
WCHAR szTitle[MAX_LOADSTRING];
WCHAR szWindowClass[MAX_LOADSTRING];
WCHAR childClass[MAX_LOADSTRING];
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_GAMEPRACTICE3, szWindowClass, MAX_LOADSTRING);
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMEPRACTICE3));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_GAMEPRACTICE3);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&wcex);
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GAMEPRACTICE3));
MSG msg;
hInst = hInstance;
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE | WS_BORDER,
0,0, 400, 600, HWND_DESKTOP, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = childClass;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hInstance = hInst;
wc.hbrBackground = CreateSolidBrush(RGB(255, 0, 0));
wc.lpfnWndProc = WndProc;
RegisterClassEx(&wc);
HWND hwnd_child = CreateWindow(childClass, NULL,
WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
0, 0, 32, 32,
hWnd, 0, hInst, 0);
ShowWindow(hwnd_child, nCmdShow);
UpdateWindow(hwnd_child);
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Any help would be appreciated :).
For Child window doesn't appear in parent's area issue, in addition to #daniel_p's answer:
WS_OVERLAPPEDWINDOW style is not relevant here. This style gives the window a title bar, a window menu, a sizing border, and minimize and maximize buttons.
Error checking is necessary. You will find that register child window class failed and return 0.
Specify a valid null-terminated string for class name. Class name is NULL is one of factors cause RegisterClassEx fail.
Initialize WNDCLASSEX struct like: WNDCLASSEX wc = {0}; Without initialization, some value which you don't set explicitly later will be garbage value. This is another factor cause RegisterClassEx fail. Or you can set every value explicitly.
With the following editions your code will work:
WCHAR childClass[MAX_LOADSTRING] = L"Child Window";
// ...
WNDCLASSEX wc = {0};
Example for error checking of RegisterClassEx function:
DWORD errCode = 0;
ATOM childClassId = RegisterClassEx(&wc);
if (!childClassId)
{
errCode = GetLastError();
MessageBox(NULL, L"RegisterClassEx failed!", L"Error", MB_ICONERROR | MB_OKCANCEL);
return 0;
}
I managed to resolve the issue.
I removed WS_OVERLAPPEDWINDOW from the creation of the child window
I added seperate Window Procedure for the child window with
DefWindowProc
I created a string for childClass and loaded it (LoadStringW)
I initialized all 11 fields of WNDCLASSEXW structure (not sure if it's necessary)
Hope it helps.

C winapi hwnd returning null

I have tried everything to find the problem, but down below is my code and hwnd returns NULL when I run the program. What might be the reasons? The code seems fine. The program was working fine for a long while until 15 mins ago. I cut this part of the source code and ran it again but it still return NULL. This is that part that I cut.
#include <windows.h>
#define IDI_MYICON 103
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
//font
/*hFont = CreateFont(40,0,0,0,700,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,TEXT("a"));
hFontIpAdres = CreateFont(25,0,0,0,700,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,TEXT("a"));
hFontKurbanSecimi = CreateFont(30,0,0,0,700,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,TEXT("a"));
*/
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
char *windowClassName = "class1";
printf("%s\n", windowClassName);
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;//MAKEINTRESOURCE(IDR_MYMENU);
wc.lpszClassName = windowClassName;
wc.hIconSm = NULL;//(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
if(!RegisterClassEx(&wc))
{
printf("window registration failed\n");
}
printf("%s\n", windowClassName);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, windowClassName,"TTr",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL
);
if(hwnd == NULL){
printf("could not create window hwnd %d\n", GetLastError());
}
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0) > 0){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Your WndProc() function doesn't return anything. CreateWindowEx() will actually call the window proc with some creation-based messages.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}

windows.h files have hundreds of syntax error

When i try to make a WinApi it make a lot of errors or even crushes down. I tried the same code in CodeBlocks(it frozens) in Visual Studio(it's tha same) and also in Dev-Cpp, where i get a lot of errors.
I tried to reinstall the programs but it did not help, but when i installed codeblocks sometimes it wrote, it has some environment problems, but i could not find out what.
I found later that the minGW file was missing but i get the same errors since.
this is the code what i try to compile and run:
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

SB_THUMBTRACK is not sent repeatedly

MSDN says the following about SB_THUMBTRACK:
The user is dragging the scroll box. This message is sent repeatedly
until the user releases the mouse button. The HIWORD indicates the
position that the scroll box has been dragged to.
However, I am only getting this message once (when I click on the scroll box).
This is my code:
#include <Windows.h>
HWND hEdit;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_HSCROLL:
if (LOWORD(wParam) == SB_THUMBTRACK)
{
// Display some text
SendMessage(hEdit, WM_CHAR, 'a', 0);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "WinClass";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
//--------------------------------------------
// Create Window
HWND hWnd = CreateWindowEx(0, "WinClass", "My Title", WS_OVERLAPPEDWINDOW, 200, 200, 500, 300, NULL, NULL, hInstance, NULL);
// Create horizontal Scrollbar
CreateWindowEx(0, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE| SBS_HORZ, 50, 50, 300, 20, hWnd, NULL, hInstance, NULL);
// Create Edit control
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 10, 10, 250, 21, hWnd, NULL, hInstance, NULL);
// Show Window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//--------------------------------------------
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Because you do not set the scrollbar info, the system could not calculate the track position.
After setting the scrollinfo,
#include "stdafx.h"
#include <Windows.h>
#include <string.h>
#include <stdlib.h>
#include <Commctrl.h>
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(lib, "Comctl32.lib")
HWND hEdit;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_HSCROLL:
if (LOWORD(wParam) == SB_THUMBTRACK)
{
int i = 0;
char buf[3];
_itoa_s(HIWORD(wParam), buf, 3, 10);
SetWindowText(hEdit, buf);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "WinClass";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
//--------------------------------------------
InitCommonControls();
// Create Window
HWND hWnd = CreateWindowEx(0, "WinClass", "My Title", WS_OVERLAPPEDWINDOW, 200, 200, 500, 300, NULL, NULL, hInstance, NULL);
// Create horizontal Scrollbar
HWND hScroll = CreateWindowEx(0, "SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ, 50, 50, 300, 20, hWnd, NULL, hInstance, NULL);
// Create Edit control
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 10, 10, 250, 21, hWnd, NULL, hInstance, NULL);
SCROLLINFO si = {0};
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = 100;
si.nPage = 10;
si.nPos = 0;
si.nTrackPos = 0;
SetScrollInfo(hScroll, SB_CTL, &si, true);
// Show Window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//--------------------------------------------
MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
everything should work well.

Resources