Callback not firing on edit control - c

I'm trying to attach a callback event handler to a windows control. My code is below:
URLInput.c
#include <windows.h>
#define ID_EDITCHILD 100
LRESULT CALLBACK URLInputWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) // Breakpoint set here never fires
{
...
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
HWND URLInput(HWND hwnd)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSW wc = { 0 };
wc.lpszClassName = L"Edit Control";
wc.lpfnWndProc = URLInputWndProc;
wc.hInstance = hInstance;
RegisterClassW(&wc);
hwnd = CreateWindowExW(
0,
L"EDIT",
NULL,
WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOVSCROLL,
0,
0,
100,
100,
hwnd,
(HMENU) ID_EDITCHILD,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
if (hwnd == NULL) {
return 0;
}
return hwnd;
}
In main.c I call like so:
INT WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
...
URLInputHwnd = URLInput(hwnd);
...
It renders fine. But, if I set a breakpoint on line 11 switch(uMsg) it never breaks. I'm expecting it to break when the window is created for example. Or, when entering text into the input. But this doesn't happen.
I've checked the MSDN documentation, although I can't find anything on using WNDCLASS with controls.
Any ideas where I'm going wrong?

Thanks to #Thomas for help in the comments. I solved my problem subclassing the created component.
URLInput.c
#include <windows.h>
#define ID_EDITCHILD 100
static WNDPROC oldURLInputProc = 0;
LRESULT CALLBACK URLInputWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
/* Do something with messages */
}
return CallWindowProc(oldURLInputProc, hwnd, uMsg, wParam, lParam);
}
HWND URLInput(HWND hwnd)
{
return CreateWindowExW(
0,
L"EDIT",
NULL,
WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOVSCROLL,
0,
0,
100,
100,
hwnd,
(HMENU) ID_EDITCHILD,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL
);
}
void setOldURLInputProc(WNDPROC wndProc)
{
oldURLInputProc = wndProc;
}
And in main.c:
URLInputHwnd = URLInput(hwnd);
/* Error checking */
setOldURLInputProc((WNDPROC)SetWindowLongPtr (URLInputHwnd, GWLP_WNDPROC, (LONG_PTR)URLInputWndProc));
The Microsoft documentation helped: https://learn.microsoft.com/en-us/windows/desktop/controls/subclassing-overview
Everything works fine.

Related

Win32 - Make part of window a translucent while another part opaque?

I want one part of a window to display an image with a certain opacity while the other part to work as normal. Both parts shouldn't pass clicks through.
I have tried making the main window a certain colour then using SetLayeredWindowAttributes to make that colour transparent(so only the client area is transparent). Then having a child window over it with my translucent image. However the clicks pass through the window(even though I don't have WS_EX_TRANSPARENT). Alphablend doesn't seem to works since the bitmap isn't 32bmp. So now I am trying to use updatelayeredwindows but I am having trouble setting the region to update it.
case WM_CREATE:
hbmp = (HBITMAP)LoadImageA(NULL, "courtyard.bmp", IMAGE_BITMAP, 1920, 1080, LR_LOADFROMFILE);
HDC hdc = CreateCompatibleDC(NULL);
HBITMAP hbmp_old = (HBITMAP)SelectObject(hdc, hbmp);
POINT dcOffset = {0, 0};
SIZE size = {600, 395};
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 100, 0};
RECT wrect;
GetClientRect(hwnd, &wrect);
wrect.top = wrect.top + 43;
UPDATELAYEREDWINDOWINFO info = {sizeof(info), GetDC(NULL), NULL, &size, hdc, &dcOffset, 0, &bf, ULW_ALPHA, &wrect};
UpdateLayeredWindowIndirect(hwnd, &info);
SelectObject(hdc, hbmp_old);
DeleteDC(hdc);
DeleteObject(hbmp);
HWND hbutton = CreateWindowExA(0,
"BUTTON",
"X",
WS_VISIBLE | WS_CHILD | BS_FLAT,
10,
10,
100,
100,
hwnd,
(HMENU)NULL,
NULL,
(LPVOID)NULL);
break;
The parts out of wrect are just a black translucent colour.
Here is my main window:
hwnd = CreateWindowExA(WS_EX_OVERLAPPEDWINDOW | WS_EX_LAYERED,
window_name,
window_title,
WS_OVERLAPPEDWINDOW,
(monitor_dimension.width - window_width) / 2,
(monitor_dimension.height - window_height) / 2 - 75,
window_width,
window_height,
(HWND)NULL,
(HMENU)NULL,
hInstance,
(LPVOID)NULL);
I get the result using SetLayeredWindowAttributes(hWnd, RGB(255, 0, 0), 0, LWA_COLORKEY); without manifest and the clicks don't pass through.
The following code adapted from SetLayeredWindowAttributes() causes mouse clicks to go through after minimizing window | WinAPI.
// WindowsProject2.cpp : Defines the entry point for the application.
//
#include "framework.h"
#include "WindowsProject2.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
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);
// TODO: Place code here.
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWSPROJECT2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT2));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
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_WINDOWSPROJECT2));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT2);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd, RGB(255, 0, 0), 0 /*doesn't matter*/, LWA_COLORKEY);
HWND hbutton = CreateWindowExA(0,
"BUTTON",
"X",
WS_VISIBLE | WS_CHILD | BS_FLAT,
10,
10,
100,
100,
hWnd,
(HMENU)NULL,
NULL,
(LPVOID)NULL);
/*HWND hbackground = CreateWindowEx(0,
L"STATIC",
NULL,
WS_CHILD | WS_VISIBLE | SS_BITMAP,
0,
0,
600,
400,
hWnd,
NULL,
NULL,
(LPVOID)NULL);
setImage(hbackground, L"test.bmp", 600, 400);*/
//SetWindowLong(hbackground, GWL_EXSTYLE, GetWindowLong(hbackground, GWL_EXSTYLE) | WS_EX_LAYERED);
//SetLayeredWindowAttributes(hbackground, 0, (255 * 50) / 100, LWA_ALPHA);
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
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);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
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;
}

Button didn't show up when menu value is set and shows odd style when not set

I'd like to set a specific window as the parent of a button, but I'm getting an expected behavior.
When the hMenu value on CreateWindow() is set, the button don't show up:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
(HMENU)1,
NULL, NULL);
But when I remove the hMenu parameter, the button does show up, but in a odd style:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
I'm not passing the HWND returned by the CreateWindow() of the main window into hwndParent of the button because they aren't called in that order.
The below code is a reduced version from my real one.
What am I missing?
Full code:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
HWND
hwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
HWND hButton = CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
SetParent(hButton, hwndMainWindow);
ShowWindow(hButton, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
You are not specifying the WS_CHILD style on the button. SetParent() does not set this style for you.
When you set the "parent" of a window that does not have WS_CHILD, you are actually setting its "owner" instead. Owner and Parent are not the same thing. Also see A window can have a parent or an owner but not both.
Your button does not appear in the main window because the button is not a child of the main window.
So, when creating the button, you need to include the WS_CHILD style. You should also include the WS_VISIBLE style instead of using ShowWindow() (unless you want to create the button hidden initially). And you should specify the parent window at the time of creation, instead of using SetParent().
You should also move your button creation into the WM_CREATE handler of your main window's WndProc().
Try this:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&wc);
HWNDhwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
ShowWindow(hwndMainWindow, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindow(L"Button",
L"Click me!",
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
20,
50,
60,
90,
hwnd,
(HMENU)1,
NULL, NULL);
break;
case WM_COMMAND:
if ((LOWORD(wParam) == 1) && (HIWORD(wParam) == BN_CLICKED)) {
MessageBox(hwnd, L"Yea, you clicked me!", L"Window", MB_OK);
return 0;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

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);
}

An issue about WM_INPUT and GetPixel

I don’t know what title should I use, but please read this.
I’m making an program that displays the color at the mouse pointer location. I want to use WM_INPUT because WM_MOUSEMOVE is not update quickly enough.
Here’s some of my main code.
#include <Windows.h>
#include <WindowsX.h>
/* void Cls_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput) */
#define HANDLE_WM_INPUT(hWnd, wParam, lParam, fn) \
((fn)((hWnd), GET_RAWINPUT_CODE_WPARAM(wParam), (HRAWINPUT)(lParam)), 0L)
static LPCTSTR main_window_class_name = TEXT("MainWindow");
static HDC hdc_screen;
static COLORREF color;
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct);
void MainWindow_OnDestroy(HWND hWnd);
void MainWindow_OnPaint(HWND hWnd);
void MainWindow_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput);
ATOM RegisterMainWindowClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = 0;
wcex.lpfnWndProc = MainWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
wcex.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = main_window_class_name;
wcex.hIconSm = wcex.hIcon;
return RegisterClassEx(&wcex);
}
HWND CreateMainWindow(HINSTANCE hInstance)
{
return CreateWindow(main_window_class_name, TEXT("WhatColor"), WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, HWND_DESKTOP, NULL, hInstance, NULL);
}
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
HANDLE_MSG(hWnd, WM_CREATE, MainWindow_OnCreate);
HANDLE_MSG(hWnd, WM_DESTROY, MainWindow_OnDestroy);
HANDLE_MSG(hWnd, WM_PAINT, MainWindow_OnPaint);
HANDLE_MSG(hWnd, WM_INPUT, MainWindow_OnInput);
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
RAWINPUTDEVICE rid[1];
UNREFERENCED_PARAMETER(lpCreateStruct);
rid[0].usUsagePage = 1;
rid[0].usUsage = 2;
rid[0].dwFlags = 0;
rid[0].hwndTarget = hWnd;
RegisterRawInputDevices(rid, 1, sizeof(rid[0]));
hdc_screen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
return TRUE;
}
void MainWindow_OnDestroy(HWND hWnd)
{
UNREFERENCED_PARAMETER(hWnd);
DeleteDC(hdc_screen);
PostQuitMessage(EXIT_SUCCESS);
}
void MainWindow_OnPaint(HWND hWnd)
{
static PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
void MainWindow_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput)
{
static RAWINPUT raw_input;
static UINT raw_input_size = sizeof(raw_input);
static POINT point;
UNREFERENCED_PARAMETER(inputCode);
GetRawInputData(hRawInput, RID_HEADER, &raw_input, &raw_input_size, sizeof(raw_input.header));
if (raw_input.header.dwType == RIM_TYPEMOUSE)
{
GetCursorPos(&point);
color = GetPixel(hdc_screen, point.x, point.y);
DeleteBrush(SetClassLong(hWnd, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(color)));
InvalidateRect(hWnd, NULL, TRUE);
}
}
The problem is the program seems to process WM_INPUT message again and again, and the main window is stuck. If I remove
color = GetPixel(hdc_screen, point.x, point.y);
the window is normal, but I can’t get the color I want.
I think it’s better if you try to test my code.
What should I do to fix this?
I’ll use Timer and process WM_TIMER message instead.

Up-Down control taller than buddy

Plain C, winapi app.
On a dialog box created from a resource script it fits perfectly, but created with CreateWindowEx the Up-Down control is taller than the buddy window (edit control) by one pixel on either side.
It's not that big of a deal, but it's pretty nagging. I tried everything I could think of and couldn't get it fixed, any help is appreciated.
Here's the code:
#include <Windows.h>
#include <Commctrl.h>
#include <stdio.h>
#define print(...) sprintf(dbg, __VA_ARGS__);\
WriteConsoleA(h_con_out, dbg, strlen(dbg), NULL, NULL)
TCHAR *app_name = TEXT("ud");
HANDLE h_con_out;
char dbg[80];
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
HWND hwnd;
MSG msg;
WNDCLASSEX wcx;
INITCOMMONCONTROLSEX icx = {sizeof(icx), ICC_STANDARD_CLASSES | ICC_UPDOWN_CLASS};
AllocConsole();
h_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
memset(&wcx, 0, sizeof(wcx));
wcx.cbSize = sizeof(wcx);
wcx.lpfnWndProc = WndProc;
wcx.hInstance = hInstance;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wcx.lpszClassName = app_name;
if(!RegisterClassEx(&wcx)){
MessageBox(NULL, TEXT("This program requires Windows 2000!"), app_name, MB_ICONERROR);
return 0;
}
InitCommonControlsEx(&icx);
hwnd = CreateWindowEx(
0, app_name, app_name,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 200, 100,
NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while((GetMessage(&msg, NULL, 0, 0)) != 0){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
static HWND hEd, hUd;
switch(msg){
case WM_CREATE:
hEd = CreateWindowEx(
WS_EX_CLIENTEDGE, WC_EDIT, NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER |
ES_RIGHT | ES_NUMBER,
5, 5, 52, 23,
hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL
);
hUd = CreateWindowEx(
0, UPDOWN_CLASS, NULL,
WS_VISIBLE | WS_CHILD |
UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_HOTTRACK | UDS_SETBUDDYINT | UDS_AUTOBUDDY,
0, 0, 0, 0,
hwnd, NULL, ((LPCREATESTRUCT) lParam)->hInstance, NULL
);
SendMessage(hUd, UDM_SETRANGE, 0, 10 | 1 << 16);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Remove WS_BORDER from the edit controls style.

Resources