I have created a working application with pure win32 APIs and C. It has a shared "status area" on top. Rest of the area displays device information (multiple fields per device).
How do I make the device information area only scrollable?
All my widgets are currently attached to single main window handle. See here the picture about what I want :
There must be a simple way to like group the widgets of bottom page and attach scrollbar to only the group, but I cannot seem to find a working technique with google. I guess my problem is I do not know hot to create groups of widgets or something. Attaching scrollbar to to the full window works fine but I want only partial.
For those interested: I'm using Dev-C++ 5.11 with TDM-GCC 4.9.2 . I don't have and won't have a resource editor. It is all in C code.
Help!
Edit1: Ok, I believe the correct term I need to search for is "child windows" per https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows
Edi2: This old scavenged code worked somewhat: https://cboard.cprogramming.com/windows-programming/94197-creating-child-window-parent-window-post676608.html#post676608 . It creates ugly window inside window but it is what I need to get started.
Ok, i reduced the code into a minimum: https://gist.github.com/usvi/b39713e270f1f75880698baacd1774b4 or
#include <windows.h>
LRESULT CALLBACK HelloWndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCMLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloApplication");
HWND hwnd,hwnd2;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = HelloWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(long);
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 95/98/NT"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName,
TEXT("Hello World for Windows"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
400,
400,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
hwnd2 = CreateWindow(szAppName,
TEXT("Hello World"),
WS_CHILD | WS_VISIBLE | WS_VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
300,
hwnd,
NULL,
hInstance,
NULL);
ShowWindow(hwnd2, iCmdShow);
UpdateWindow(hwnd2);
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message){
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello, Windows"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
And it works, see:
My problem basically was that child window creation CreateWindow() first parameter was omitted or otherwise wrong. It needs to match named and registered WNDCLASS.
NOTE: This is a rough rough rough sketch, I might need to make 2 classes and second message handler. But this is a good start.
Related
I am replacing BeginPaint-EndPaint in a simple window with GetDC-ReleaseDC.
I am reading Charles Petzold Programming Windows 5th Edition.
Here is my code with the changes and the lines changed as comments:
#include<Windows.h>
#include<mmsystem.h>
LRESULT CALLBACK myWndProc(HWND windowHandle, UINT winMessage, WPARAM wParam, LPARAM lParam);
int
WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
WNDCLASSEX myWndClass;
MSG msg;
HWND myWndHandle;
wchar_t szmyWndClassName[] = TEXT("SotoWindClass");
wchar_t szmyWndowName[] = TEXT("SotoWindow");
myWndClass.cbClsExtra = 0;
myWndClass.cbSize = sizeof(WNDCLASSEX);
myWndClass.cbWndExtra = 0;
myWndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
myWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
myWndClass.hIcon = LoadIcon(NULL, IDI_HAND);
myWndClass.hIconSm = NULL;
myWndClass.hInstance = hInstance;
myWndClass.lpfnWndProc = myWndProc;
myWndClass.lpszClassName = szmyWndClassName;
myWndClass.lpszMenuName = NULL;
myWndClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&myWndClass))
{
MessageBoxEx(NULL, TEXT("I need at least WINNT"), szmyWndClassName, MB_ICONERROR, 0);
}
myWndHandle = CreateWindowEx(
WS_EX_LEFT,
szmyWndClassName,
szmyWndowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(myWndHandle, iCmdShow);
UpdateWindow(myWndHandle);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK myWndProc(HWND windowHandle, UINT winMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
//PAINTSTRUCT ps;
RECT rc;
wchar_t displayText[] = TEXT("Display My Text!!!!");
switch (winMessage)
{
case WM_CREATE:
{
PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
return(0);
}break;
case WM_PAINT:
{
/*
hdc = BeginPaint(WindowHandle, &ps);
DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(WindowHandle, &ps);
return(0);
*/
hdc = GetDC(windowHandle);
GetClientRect(windowHandle, &rc);
//ValidateRect(windowHandle, &rc);
DrawText(hdc, displayText, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
ReleaseDC(windowHandle, hdc);
return(0);
}
case WM_DESTROY:
{
PlaySound(NULL, NULL, SND_FILENAME | SND_ASYNC);
PostQuitMessage(0);
return(0);
}
}
return(DefWindowProc(windowHandle, winMessage, wParam, lParam));
}
My question is:
Why DrawText is still displaying the message when i haven't called ValidateRect?
From what i understand(which is obviously incorrect) the text inside RECT rc shouldn't appear, unless I call ValidateRect.
When the window is displayed the text drawn is flickering which i assume happens because Windows are calling WM_PAINT and are trying to validate rc (my client area) but DrawText still manages to display the text line every time.
I am a bit confused.
Your text is rendered again and again, because you haven't called ValidateRect. EndPaint calls ValidateRect to mark the area rendered during this paint cycle as valid, i.e. doesn't need rendering.
Leaving an area marked as invalid doesn't stop you drawing to it, it just means the system won't think you have drawn to it and will keep asking you to.
(posted as community wiki, since the question was answered in the comments)
I am experimenting on Windows 7 64 bit OS with win32 API.When i run my Program on debug mode my window appears but i have 2 bugs. Firt things first here is my api code modified from Charles Petzold book Ch3:
#include<Windows.h>
#include<mmsystem.h>
LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, PSTR szCmdLine, int iCmdShow)
{
WNDCLASSEX MyWindowsClass;
static wchar_t szMyWindowsClassName[] = TEXT("The Name of My Window Class");
static wchar_t szAppName[] = TEXT("AppName");
HWND myWindowHandle;
MSG msg;
MyWindowsClass.hInstance = hInstance;
MyWindowsClass.style = CS_HREDRAW | CS_VREDRAW;
MyWindowsClass.lpfnWndProc = HandleMyWindowsClassMessages;
MyWindowsClass.lpszClassName = szMyWindowsClassName;
MyWindowsClass.cbSize = sizeof(WNDCLASSEX);
MyWindowsClass.cbClsExtra = 0;
MyWindowsClass.cbWndExtra = 0;
MyWindowsClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
MyWindowsClass.hCursor = LoadCursor(NULL, IDC_ARROW);
MyWindowsClass.hIcon = LoadIcon(NULL, IDI_SHIELD);
MyWindowsClass.hIconSm = NULL;
MyWindowsClass.lpszMenuName = NULL;
if (!RegisterClassEx(&MyWindowsClass))
{
MessageBoxEx(0, TEXT("This Programm Requires WINNT!"), szMyWindowsClassName, MB_ICONERROR, 0);
return(0);
}
myWindowHandle = CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
szMyWindowsClassName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(myWindowHandle, iCmdShow);
UpdateWindow(myWindowHandle);
while (GetMessage(&msg, myWindowHandle, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
//wchar_t szGreeting[] = TEXT("Heeeey");
HDC hdc;
PAINTSTRUCT ps;
switch (Message)
{
case WM_CREATE:
{
PlaySound(TEXT("D:\\mp3\\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
return(0);
} break;
case WM_PAINT:
{
hdc = BeginPaint(WindowHandle, &ps);
DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &ps.rcPaint, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
//TextOut(hdc, 0, 0, szGreeting, (int)wcslen(szGreeting));
EndPaint(WindowHandle, &ps);
return(0);
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
}break;
}
return(DefWindowProc(WindowHandle, Message, wParam, lParam));
}
Bug1:PlaySound keeps playing the wav even when i have closed-destroyed the Window.When I used the original example with plain WNDCLASS the bug dissapeared!
So I must be doing something wrong using WNDCLASSEX ???.
Also in this bug to end execution of debbuging I have to press Shift+F5.
Bug2:TextOut vs DrawText
Info:I have only 1 screen.I program on my laptop.
When I use drawText and the text in my window goes out of my desktop screen borders the text just doesnt update correclty.
When I use TextOut the bug dissapears!!!
Why???
Below i have some pitures ordered to explain this.
The Program starts in debug mode
Moving the window out of Desktop borders(including the displayed text)
Moving the window back inside my desktop area(the text has been mutated)
Window is destroyed and sound will keep playing even when the wav ends.
Any help in any of the 2 bugs would be greatly appreciated.
2nd version of my WndProc:
LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
//wchar_t szGreeting[] = TEXT("Heeeey");
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
rc.left = 50; rc.top = 100; rc.right = 200; rc.bottom = 200;
switch (Message)
{
case WM_CREATE:
{
PlaySound(TEXT("D:\\mp3\\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
return(0);
} break;
case WM_PAINT:
{
hdc = BeginPaint(WindowHandle, &ps);
DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
//TextOut(hdc, 0, 0, szGreeting, (int)wcslen(szGreeting));
EndPaint(WindowHandle, &ps);
return(0);
}break;
case WM_DESTROY:
{
PlaySound(NULL, NULL, SND_FILENAME | SND_ASYNC);
PostQuitMessage(0);
return(0);
}break;
}
return(DefWindowProc(WindowHandle, Message, wParam, lParam));
}
Call PlaySound( NULL, NULL, SND_FILENAME | SND_ASYNC) before PostQuitMessage to stop the sound.
About DrawText - note that BeginPaint returns rectangle rcPaint for the region which needs redraw. If you are using it for start point of DrawText, the text will appear at different places. For example - when first created, the region will start at 0,0. Then you can move another window over DrawText application window and it can require repaint from point 80,100 to lower right corner. Try with absolute (client) coordinates, e.g. define RECT rc and set rc.left = 50; rc.top = 100; rc.right = 200; rc.bottom = 200; (always the same position).
I am trying to learn win32 API using Programming Windows fifth Edition.
As I was experimenting with some Identifiers I noticed something that I am not able to understand why is happening.I` ll be more specific, here is my code:
#include<Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int
WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HELLOWIN");
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_SHIELD);
wndclass.hCursor = LoadCursor(NULL, IDC_CROSS);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(0, TEXT("This Programm Requires WINNT!"), szAppName, MB_ICONERROR);
return(0);
}
hwnd = CreateWindow(szAppName, //window class name
TEXT("The Hello Program"), //window caption
WS_OVERLAPPEDWINDOW, //window style
CW_USEDEFAULT, //initial x position
CW_USEDEFAULT, //initial y position
CW_USEDEFAULT, //initial x size
CW_USEDEFAULT, //initial y size
NULL, //parent window handle(we have top-level window)
NULL, //window menu handle
hInstance, //programm instances handle
NULL); //creation parameters
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
{
PlaySound(TEXT("D:\\mp3\\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0;
} break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
} break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
With this code everything works great and as expected but...
when i change:
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
to
wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
the cursor icon is lost on the background and is only visisble in the small line
in which i use drawText().What confuses me is that this doesnt happen when my background is white(WHITE_BRUSH).
Could someone explain why?
PS:If this behaviour is explained later in the book (I am finishing chapter 3 currently) just type Read more so i don`t waste you time.
Thank you in advance.
What is probably happening is that the 'cross' cursor that you are using is a very thin cursor implemented (either by windows or by the hardware) by NEGating the underlying pixels instead of painting above them. This works fine for all colors except the 0x808080 gray, because negating 0x808080 still gives 0x808080, so the cursor is invisible. Try using light gray, dark gray, or another cursor which is not so thin.
I am new to plain winapi c and was wondering if there is any simple method for adding an image to my GUI, if possible I would like this image to essentially part of the code so that I only have to send the single executable file when sending others the GUI.
EDIT:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HBITMAP g_hbmBall = NULL;
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_CREATE:
g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
if(g_hbmBall == NULL)
MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
break;
case WM_PAINT:
{
BITMAP bm;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_hbmBall);
GetObject(g_hbmBall, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
DeleteObject(g_hbmBall);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
You can add the image data to your executable's resources at compile-time via an .rc file, then load the image at runtime via LoadImage(). If you put a STATIC control on your UI, you can send it an STM_SETIMAGE message to display the image.
Image should be a bitmap, you should make it a resource with your resource editor and use LoadBitmap or LoadImage to load it in your exe. Use BitBlt , StretchBlt or TransparentBlt to draw it ( use last two if you want to shrink/enlarge it to fit your window-TransparentBlt also makes parts of your image transparent-see documentation ). Do not forget to delete the resource when you are done-usually in your WM_CLOSE handler with DeleteObject API.
EDIT:
As Remy Lebeau said, you can use workaround by putting a static control on your window and set it to display image. I do not know what suits you better since your post is scarse on information. I still suggest to use GDI to draw a picture since you can try to use all kind of stretching modes to improve images quality.
This tutorial has some examples, and is good in general for learning the Win32 API.
Good luck.
Best regards.
As MSDN describes:
When the mouse moves over a window, the window receives a WM_SETCURSOR message (unless another window has captured the mouse).
If the application passes WM_SETCURSOR to DefWindowProc, the DefWindowProc function uses the following algorithm to set the cursor image:
If the window has a parent, forward the WM_SETCURSOR message to the parent to handle.
Otherwise, if the window has a class cursor, set the cursor to the class cursor.
If there is no class cursor, set the cursor to the arrow cursor.
And here's my source code:
#include <tchar.h>
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInsTance, LPTSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = { 0 };
HWND hWnd;
BOOL ret;
MSG msg;
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
// wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = TEXT("MainWindow");
wcex.hIconSm = wcex.hIcon;
RegisterClassEx(&wcex);
hWnd = CreateWindow(wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (ret = GetMessage(&msg, NULL, 0, 0))
{
if (ret == -1)
{
return EXIT_FAILURE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(EXIT_SUCCESS);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
When I move my cursor quickly over the window, the cursor doesn't change to an arrow, it become a resize arrow; if I set wcex.hCursor to LoadCursor(NULL, IDC_ARROW), everything will be all right. My question is: why doesn't my code work as MSDN says?
I mean, if I don't set wcex.hCursor, and I don't handle the WM_SETCURSOR message, the DefWindowProc should "set the cursor to the arrow cursor", but it seems it doesn't. Why is that?
See description of the hCursor member of the WNDCLASSEX:
A handle to the class cursor. This member must be a handle to a cursor
resource. If this member is NULL, an application must explicitly set
the cursor shape whenever the mouse moves into the application's
window.
WNDCLASSEX structure