How to set chinese text into an edit field in Windows - c++

I am new to using international languages in my win32 program in C++. I have a simple window created with an edit field inside. I want to set a chinese hardcoded text into the edit field. I am using SetWindowText but the output has only question marks and | character. What am I missing? My code file is pasted below. I have tried WM_SETTEXT but no luck.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <strsafe.h>
#include <iostream>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
HWND edit = CreateWindowEx(0, L"Edit", L"", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 200, 50, hwnd, NULL, hInstance, NULL);
SetWindowTextW(edit, L"銷售回扣");
//SendMessage(edit, WM_SETTEXT, 0, (LPARAM)(L"銷售回扣"));
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Related

window fails to initiate when specifying a custom class name registered with RegisterClass to CreateWindowEx but only the second time I do it

I'm creating a window that's supposed to contain buttons.
When I create the first window (the container) I use a WNDCLASS to specify a WindowProc callback function to lpfnWndProc and it works as intended. When I do it the second time with a window, specifying a callback used to detect when the button is clicked, it doesn't work; the CreateWindowEx call there returns NULL (comment below shows where).
When I don't create WNDCLAS wB below and specify some other valid lpClassName to CreateWindowEx instead, such as Button it works fine.
code used
#pragma comment(linker, "/entry:wWinMainCRTStartup")
#include <windows.h>
#include <iostream>
HWND button;
LRESULT CALLBACK ButtonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine,
int nCmdShow) {
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"textedit";
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0, wc.lpszClassName, L"textedit", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 340, 240, NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
return 0;
}
HWND hWndEdit = CreateWindowEx(WS_EX_CONTROLPARENT, L"Edit", L"id here",
WS_BORDER | WS_CHILD | WS_VISIBLE, 94, 20, 140,
40, hwnd, NULL, NULL, NULL);
// if I leave wcB unused/remove it and
// specify L"Button" as the lpClassName to CreateWindowEx below, the button displays
WNDCLASS wcB = {};
wcB.lpfnWndProc = ButtonWindowProc;
wcB.hInstance = hInstance;
wcB.lpszClassName = L"modify";
RegisterClass(&wcB);
ShowWindow(hwnd, nCmdShow);
// doing the exact same thing I did when creating the first window
// but it fails to create the window
HWND hButton =
CreateWindowEx(0L, L"modify", L"modify", BS_FLAT | WS_VISIBLE | WS_CHILD,
94, 70, 140, 50, hwnd, NULL, hInstance, NULL);
ShowWindow(hButton, nCmdShow);
// here hButton is NULL <----------------------
if (hButton == NULL) {
return 0;
}
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK ButtonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case BN_CLICKED:
std::cout << "clicked";
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
return 0;
return DefWindowProc(hwnd, uMsg, wParam, lParam);
};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
GetLastError() returns 1400, but I don't understand how the handle hwnd could possible be invalid because as I mentioned before, when I just change the lpClassName I pass to CreateWindowEx, it works without errors.
I would appreciate any help in finding out why the window (the HWND of which is hButton) does not initiate, and possible workarounds.
The solution to the problem in the title was solved by the comment by Igor Tandetnik:
ButtonWindowProc returns 0 for all messages it doesn't handle, and doesn't pass them to DefWindowProc. In particular, it returns 0 in response to WM_NCCREATE, which is a signal that the window creation has failed. You probably didn't mean to put return 0; right before return DefWindowProc(...);
After fixing that, the window was created but was invisible.
To fix that I used FillRect with a valid brush handle
SetDCBrushColor(hdc, bkcolor);
SetBkColor(hdc, RGB(187, 189, 189));
FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(DC_BRUSH));
To detect left mouse button clicks you need to check for the WM_LBUTTONDOWN message.

why is this visual studios file not compiling

so I'm a bit new to c++/windows.h programming and I am in the middle of learning basic functions like how to create a window....and I tried to run this code (in visual studio 2022)that was in microsoft as sort of an example code but it still wouldn't compile giving the error -
Error LNK2019 unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ) MSVCRTD.lib(exe_main.obj)
Here is the code I tried to run (its an unchanged example from microsoft of how to make a window)-
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
I'd like to know how to fix this....thanx in advance
Create a new project-> Windows Desktop Wizard->Desktop Application.
Check Empty Project.
Add a new cpp file and copy your code.

The Bottom Border of a simple Windows Application keeps disappearing and reaapearing when resizing the window

Here's a simple Win32 Application that I copied from the official MSDN docs (link):
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_DESKTOP+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
The only difference is I used COLOR_DESKTOP instead of COLOR_WINDOW in FillRect() (this problem occurs in both the cases).
Whenever I resize the window, the bottom border keeps disappearing and then reappearing as I resize it further. Can anyone tell what's happening?
Here's GIF to show the bottom border disappearing when resizing:
I suggest you could try to enable DPI awareness: Property -> Manifest Tool ->Input and Output -> DPI Awareness.

open window program in visual c++

I just started to learn windows app development in c++ and I found some program code on Microsoft docs that all it should do is open simple window. I tried to build it on visual studio and it was built but it didn't run. And when I tried to compile and run it with the local debugger I got some error that I have no idea what is it about. I'd like to get some help with it.
Here is the code and the error message.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Unable to add thumbnail buttons to a window?

I'm trying to add thumbnail buttons to a window, but there is no error and no thumbnail button is shown. I read the following pages for reference:
Your First Windows Program;
ITaskbarList3::ThumbBarAddButtons method;
some code on github.
Environment: win10 64bit, vs2015
// function WindowProc and wWinMain are copied from msdn directly.
#include "stdafx.h"
#include <windows.h>
#include "shobjidl.h"
#include <exception>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT addThumbnailButtons(HWND hwnd) {
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr)) {
ITaskbarList4* ptbl = nullptr;
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&ptbl));
if (SUCCEEDED(hr)) {
// create 2 buttons
THUMBBUTTON thmb[2] = {};
thmb[0].dwMask = THB_TOOLTIP;
thmb[0].iId = 0;
wcscpy_s(thmb[0].szTip, L"Button 1");
thmb[1].dwMask = THB_TOOLTIP;
thmb[1].iId = 1;
wcscpy_s(thmb[1].szTip, L"Button 2");
//ptbl->HrInit();
hr = ptbl->ThumbBarAddButtons(hwnd, ARRAYSIZE(thmb), thmb);
ptbl->Release();
return hr;
}
else {
throw std::exception("createInstance failed");
}
}else{
throw std::exception("coinitialize failed");
}
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
HRESULT hr = addThumbnailButtons(hwnd);
if (FAILED(hr)) {
throw std::exception("addbuttons failed");
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Per the ITaskBarList3 documentation:
When an application displays a window, its taskbar button is created by the system. When the button is in place, the taskbar sends a TaskbarButtonCreated message to the window. Your application should call RegisterWindowMessage(L"TaskbarButtonCreated") and handle that message in its wndproc. That message must be received by your application before it calls any ITaskbarList3 method.
You must wait for that message before calling addThumbnailButtons(), eg:
UINT uMsgTaskbarCreated;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
uMsgTaskbarCreated = RegisterWindowMessage(L"TaskbarButtonCreated");
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop.
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
default:
if ((uMsg == uMsgTaskbarCreated) && (uMsgTaskbarCreated != 0))
{
HRESULT hr = addThumbnailButtons(hwnd);
if (FAILED(hr)) {
...;
}
}
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}