WinApi, Push button are not displayed - c

I'm trying to create simple windows app uisng WinAPi.
Here is the code:
#include "stdafx.h"
#include "APIup.h"
#define MAX_LOADSTRING 100
HWND hWnd,cw13;
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
ATOM Register(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc_dla13(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_APIUP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
Register(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_APIUP));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX 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_APIUP));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_APIUP);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
ATOM Register(HINSTANCE hInstance)
{
WNDCLASSEX cw13class;
cw13class.cbSize = sizeof(WNDCLASSEX);
cw13class.style = CS_HREDRAW | CS_VREDRAW;
cw13class.lpfnWndProc = WndProc_dla13;
cw13class.cbClsExtra = 0;
cw13class.cbWndExtra = 0;
cw13class.hInstance = hInstance;
cw13class.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APIUP));
cw13class.hCursor = LoadCursor(NULL, IDC_ARROW);
cw13class.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
cw13class.lpszMenuName = NULL;
cw13class.lpszClassName = L"13class";
cw13class.hIconSm = LoadIcon(cw13class.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&cw13class);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 100, 100, NULL, NULL, hInstance, NULL);
cw13=CreateWindow(L"13class",L"Ćwiczenie 13",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,300,300,NULL,NULL,hInst,NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case ID_32771:
ShowWindow(cw13, 1);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProc_dla13 (HWND hWnd, UINT msg/*message*/, WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"button", L"Beep",
WS_VISIBLE | WS_CHILD ,
20, 50, 80, 25,
cw13, (HMENU) 1, hInst, NULL);
CreateWindowW(L"button", L"Quit",
WS_VISIBLE | WS_CHILD ,
120, 50, 80, 25,
cw13, (HMENU) 2, NULL, NULL);
break;
case WM_COMMAND:
if (LOWORD(wParam) == 1) {
Beep(40, 50);
}
if (LOWORD(wParam) == 2) {
PostQuitMessage(0);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, 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;
}
And the problem is that: when i create window 'cw13' it is created and displayed, but push buttons are not.I created two separate WndProc functions. Other messages are executed correctly( like WM_QUIT), only CreateWindowW under WM_CREATE,witch should create and show Push buttons aren't. Where is the problem?

When processing the WM_CREATE message, your call to CreateWindow(L"13class") is still running. Your cw13 variable has not been assigned yet, so you are assigning an invalid HWND as the parent of your buttons. That is why they do not appear. Use the hwnd parameter of WndProc_dla13() instead as the parent. That will be the same HWND that gets assigned to the cw13 variable once CreateWindow(L"13class") exits.

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

How to identify AppendMenu MF_POPUP Menu in the WindowProcedure?

I'm getting confused.
MF_POPUP
0x00000010L
Specifies that the menu item opens a drop-down menu or submenu. The
uIDNewItem parameter specifies a handle to the drop-down menu or
submenu. This flag is used to add a menu name to a menu bar, or a menu
item that opens a submenu to a drop-down menu, submenu, or shortcut
menu.
(https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)
Yes, but how do we now specify the uID of the Menu and refer to it in the WindowProcedure,
if the uIDNewItem parameter is now a handle to the drop-down menu or submenu.
This is a simple code sample you can refer,
#include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define EXIT_ID 1
#define SUB_ID 2
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
{
HMENU hMenubar = CreateMenu();
HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
HMENU hDisplayMenu = CreatePopupMenu(); //display is a popup-menu because it has children.
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, "File");
AppendMenu(hFileMenu, MF_STRING | MF_POPUP, (UINT_PTR)hDisplayMenu, "Display");
AppendMenu(hDisplayMenu, MF_STRING, SUB_ID, "Sub");
AppendMenu(hFileMenu, MF_STRING, EXIT_ID, "Exit");
SetMenu(hwnd, hMenubar);
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case SUB_ID:
MessageBox(hwnd, "You click Sub menu", " ", MB_OK);
break;
case EXIT_ID:
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;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = "win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow("win32", "My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Debug:
EXIT_ID and SUB_ID are the uID of the submenu. You need to define them manually.
#define EXIT_ID 1
#define SUB_ID 2
Updated:
You can use WM_MENUSELECT to get the handle to the menu that is clicked and compare their hmenus.
Sent to a menu's owner window when the user selects a menu item.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenubar;
switch (message)
{
case WM_CREATE:
{
hMenubar = CreateMenu();
HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
SetMenu(hWnd, hMenubar);
}
break;
case WM_MENUSELECT:
{
HMENU hmenu = (HMENU)lParam;
if (hmenu == hMenubar)
{
MessageBox(hWnd, L"You click main menu", L" ", MB_OK);
}
}
break;
...
Like this,

Creating an HBITMAP from pixel buffer then rendering

Ok, so I literally just started using the WinAPI for drawing bitmap images. So if my code is absolute trash, I apologize. Anyways, how the heck am I supposed to do this? Essentially, I want to create an HBITMAP object from a simple unsigned char pixel buffer using CreateBitmap() like this...
HBITMAP hbm = CreateBitmap(width, height, 1, 24, buffer);
(obviously this is 3-bytes per pixel)
That appears to work fine until I try rendering it. For now, I just wanted to keep it simple and draw a 100 by 100 black pixel square on the screen but nothing shows up. I would appreciate it if anyone could point out the mistakes in my atrocious code.
This is my setup (I am aware a lot of things could be improved I just wanted to go as minimalistic as possible for now and actually have something appear on the screen):
HBITMAP hbm = NULL;
void window_init(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static unsigned char buffer[30000] = {0};
hbm = CreateBitmap(100, 100, 1, 24, buffer);
}
void window_draw(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, hbm);
BitBlt(hdc, 100, 100, 100, 100, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: window_init(hwnd, msg, wParam, lParam); break;
case WM_PAINT: window_draw(hwnd, msg, wParam, lParam); break;
case WM_CLOSE: DestroyWindow(hwnd); break;
case WM_DESTROY: PostQuitMessage(0); break;
default: return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
Here's my entire code in case you want to copy it...
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct {
const char *wc_name;
const char *title;
unsigned int width;
unsigned int height;
} Window;
static HBITMAP hbmp = NULL;
static PAINTSTRUCT ps;
void window_create(Window *window, const char *wc_name, const char *title, unsigned int width, unsigned int height) {
window->wc_name = wc_name;
window->title = title;
window->width = width;
window->height = height;
}
void window_init(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static unsigned char buffer[30000] = {0};
hbmp = CreateBitmap(100, 100, 1, 24, buffer);
}
void window_draw(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, hbmp);
BitBlt(hdc, 100, 100, 100, 100, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);;
EndPaint(hwnd, &ps);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: window_init(hwnd, msg, wParam, lParam); break;
case WM_PAINT: window_draw(hwnd, msg, wParam, lParam); break;
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 nShowCmd) {
Window window;
window_create(&window, "Parent Window", "My Window", 1000, 1000 / 16 * 9);
WNDCLASSEX wc = {0};
MSG msg = {0};
HWND hwnd = NULL;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszClassName = window.wc_name;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, "Failed to register application window!", "WC Registration Error!", MB_ICONEXCLAMATION | MB_OK);
return -1;
}
hwnd = CreateWindowEx(
0, window.wc_name, window.title,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
window.width, window.height, NULL, NULL, hInstance, NULL
);
if (!hwnd) {
MessageBox(NULL, "Failed to launch application window!", "HWND Creation Error!", MB_ICONEXCLAMATION | MB_OK);
return -1;
}
ShowWindow(hwnd, SW_MAXIMIZE);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
CreateBitmap produces a handle to a device dependent bitmap unlike CreateDIBSection which is guaranteed to create a device-independent bitmap with the device context if it succeeds, and allows you access to the actual bits in the bitmap, unlike CreateCompatibleBitmap.
How to use CreateDIBSection:
HDC hdc = GetDC(hwnd);
BITMAPINFO bi = { 0 };
static BYTE *bits = NULL;
static unsigned char buffer[30000] = { 0 };
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = 100;
bi.bmiHeader.biHeight = -100;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biCompression = BI_RGB;
hbmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
CopyMemory(bits, buffer, 30000);
ReleaseDC(hwnd, hdc);

C win32 app there can be compile and link but show nothing to me but process.why?

there can be compile and link but show nothing to me but process.why?
i have download another Similar mine but this show me the window. i am confused.
#include<windows.h>
#include<stdio.h>
LRESULT CALLBACK WinSunProc(//可以通过MSDN查看回调函数的声明方式
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
){
WNDCLASS wndcls;//设计一个窗口类
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//黑色的刷子
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//窗口上面是应用程序的图标
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WinSunProc;/窗口过程函数。回调函数
wndcls.lpszClassName = "First MFC";//类名
wndcls.lpszMenuName = NULL; //没有菜单
wndcls.style = CS_HREDRAW | CS_VREDRAW;//CS:类的样式---水平重绘、垂直重绘
RegisterClass(&wndcls);//注册窗口
HWND hwnd;//创建窗口
hwnd = CreateWindow("MFC", "JLU", WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);//显示窗口
UpdateWindow(hwnd);
MSG msg;//消息循环机制
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HDC hDC; //Device Context的句柄
switch (uMsg) //针对不同消息处理过程
{
case WM_PAINT: //窗口重绘时,触发的消息
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd, &ps); //BeginPaint/EndPaint只能用在WM_PAINT消息中
TextOut(hDC, 50, 50, "This is first MFC Program!", strlen("This is first MFC Program!"));
EndPaint(hwnd, &ps);
break;
case WM_CHAR: //按下键盘字母键响应消息
char cArry[20];
memset(cArry, 0, 20);
sprintf(cArry, "char is %d", wParam);
MessageBox(hwnd, cArry, "WM_CHAR", MB_OKCANCEL);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "LeftMouse Click", "WM_LBUTTONDOWN", MB_OKCANCEL);
hDC = GetDC(hwnd);
TextOut(hDC, 50, 100, "MFC Program!", strlen("MFC Program!"));
ReleaseDC(hwnd, hDC);
break;
case WM_CLOSE:
if (IDOK == MessageBox(hwnd, "是否真的要退出?", "提示", MB_OKCANCEL))
{
DestroyWindow(hwnd); //销毁窗口,同时发送WM_DESTROY消息
}
break;
case WM_DESTROY:
PostQuitMessage(0); //发送WM_QUIT消息
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam); //对待不关心的消息,采用默认方式处理
}
return 0;
}
i post the WINMAIN and CALLBACK function i cant found any error. please hellp me fix this.
First of all it is not an MFC application. It is just a very simple Win32 application written in C.
As far as I can tell your WindowProc function is WinQinProc(), but for some reason you do register your window class with WinSunProc. That's your first problem. The other problem is the name of your Window class (WNDCLASS). Please note that you should also use the same Window Class name registered in CreateWindow() call.
Here is the fixed version of your application (include "tchar.h" to make app UNICODE aware):
LRESULT CALLBACK WinSunProc(//可以通过MSDN查看回调函数的声明方式
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASS wndcls;//设计一个窗口类
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//黑色的刷子
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//窗口上面是应用程序的图标
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WinSunProc;
wndcls.lpszClassName = _T("MyClassName");//类名
wndcls.lpszMenuName = NULL; //没有菜单
wndcls.style = CS_HREDRAW | CS_VREDRAW;//CS:类的样式---水平重绘、垂直重绘
RegisterClass(&wndcls);//注册窗口
HWND hwnd;//创建窗口
hwnd = CreateWindow(_T("MyClassName"), _T("JLU"), WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);//显示窗口
UpdateWindow(hwnd);
MSG msg;//消息循环机制
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HDC hDC; //Device Context的句柄
switch (uMsg) //针对不同消息处理过程
{
case WM_PAINT: //窗口重绘时,触发的消息
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd, &ps); //BeginPaint/EndPaint只能用在WM_PAINT消息中
TextOut(hDC, 50, 50, _T("This is first Win32 Program!"), _tcslen(_T("This is first Win32 Program!")));
EndPaint(hwnd, &ps);
break;
case WM_CHAR: //按下键盘字母键响应消息
char cArry[20];
memset(cArry, 0, 20);
// sprintf(cArry, "char is %d", wParam);
// MessageBox(hwnd, cArry, "WM_CHAR", MB_OKCANCEL);
break;
case WM_LBUTTONDOWN:
// MessageBox(hwnd, "LeftMouse Click", "WM_LBUTTONDOWN", MB_OKCANCEL);
hDC = GetDC(hwnd);
TextOut(hDC, 50, 100, _T("Win32 Program!"), _tcslen(_T("Win32 Program!")));
ReleaseDC(hwnd, hDC);
break;
case WM_CLOSE:
if (IDOK == MessageBox(hwnd, _T("是否真的要退出?"), _T("提示"), MB_OKCANCEL))
{
DestroyWindow(hwnd); //销毁窗口,同时发送WM_DESTROY消息
}
break;
case WM_DESTROY:
PostQuitMessage(0); //发送WM_QUIT消息
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam); //对待不关心的消息,采用默认方式处理
}
return 0;
}

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.

Resources