Sending text to button after adding image c++ - c++

I am able to add image to the button as background but later I want to add text to the button as "Weclome", I tried all possible ways using Settext, SendmessageA.
please help
#include <Windows.h>
int main()
{
MSG msg;
HWND hWnd = CreateWindow(TEXT("button"), TEXT("START"), WS_VISIBLE | WS_POPUP | WS_CHILD | WS_TABSTOP | BS_BITMAP,
250, 250, 500, 500, NULL, NULL, NULL, NULL);
HANDLE hImg = LoadImageW(NULL, L"Untitled.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
SendMessageW(hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImg);
SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"Welcome");
//SendMessageW(hWnd, WM_SETTEXT, (WPARAM) 256,NULL);
while (GetMessage(&msg, NULL, 0, 0))
{
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}

You do realize you have to create a window and then put the button inside the window?
Chances are the program is looking for a file in the wrong directory. Use full path names and do error checking to make sure the bitmap is loaded. Example:
HANDLE hImg = LoadImageW(NULL, L"c:\\fullpath\\Untitled.bmp", IMAGE_BITMAP, 0, 0,
LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (!hImg)
report error...
Don't put ShowWindow and UpdateWindow in the message loop. Just show the window and then call the message loop. Example:
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Related

How to use the SetWindowPos function?

I'd like to create a Windows app consisting of a main parent window and several child windows. Here is an excerpt of the code I have so far:
...
// -----> CHILD WINDOWS <-----
HWND hWnd_child1 = CreateWindowW(L"STATIC", L"Child 1", WS_CHILD,
0, 0, 100, 80, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child1) {
MessageBox(NULL, L"CreateWindowW Child 1", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
HWND hWnd_child2 = CreateWindowW(L"STATIC", L"Child 2", WS_CHILD,
10, 10, 160, 120, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child2) {
MessageBox(NULL, L"CreateWindowW Child 2", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
HWND hWnd_child3 = CreateWindowW(L"STATIC", L"Child 3", WS_CHILD,
20, 20, 160, 120, hParentWnd, nullptr, hInstance, nullptr);
if (!hWnd_child3) {
MessageBox(NULL, L"CreateWindowW Child 3", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
ShowWindow(hWnd_child3, nCmdShow);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
ShowWindow(hWnd_child2, nCmdShow);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
ShowWindow(hWnd_child1, nCmdShow);
ShowWindow(hParentWnd, nCmdShow);
UpdateWindow(hParentWnd);
// -------------------
...
The problem is with the SetWindowPos() function. I can't understand how it really works. I thought that calling it like this:
ShowWindow(hWnd_child3, nCmdShow);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
ShowWindow(hWnd_child2, nCmdShow);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
ShowWindow(hWnd_child1, nCmdShow);
Would move the Child 1 window to the top of all the app windows (as the doc says for the HWND_TOP option: Places the window at the top of the Z order).
BUT, the windows are still drawned in the creation order:
Shouldn't SetWindowPos() move firstly Child 2 over Child 3, and next Child 1 over Child 2, making the windows laid up in the reverse order than they were created, with Child 1 on top?
Make the child windows all have the window style WS_CLIPSIBLINGS along with WS_CHILD etc.
From Microsoft's documentation:
If WS_CLIPSIBLINGS is not specified and child windows overlap, it is
possible, when drawing within the client area of a child window, to
draw within the client area of a neighboring child window.
Basically if the child windows do not clip each other then the order in which they are painted (which is arbitrary) determines the visual z-order.
Below for instance is your code with the message box stuff removed, using WS_VISIBLE instead of ShowWindow, adding a border for visibility, and using WS_CLIPSIBLINGS.
BOOL CreateChildren(HWND hParentWnd) {
HWND hWnd_child1 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 1", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
0, 0, 100, 80, hParentWnd, nullptr, g_hInstance, nullptr);
HWND hWnd_child2 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 2", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
10, 10, 160, 120, hParentWnd, nullptr, g_hInstance, nullptr);
HWND hWnd_child3 = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", L"Child 3", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
20, 20, 160, 120, hParentWnd, nullptr, g_hInstance, nullptr);
SetWindowPos(hWnd_child2, HWND_TOP, 10, 10, 100, 80, NULL);
SetWindowPos(hWnd_child1, HWND_TOP, 0, 0, 100, 80, NULL);
UpdateWindow(hParentWnd);
return TRUE;
}
which yields
child1 is on top.

Button Press Handling win32 c++

I'm creating a plugin which loads a native window with 2 buttons, on press they should make a message box pop-up but there's no pup-up
Creating a thread for the message loop
//create message thread
class startMessageThreadLoop
{
public:
static DWORD WINAPI StaticThreadStart(void* Param)
{
MessageBox(hWnd, L"StaticThreadStart", L"StaticThreadStart", 0);
startMessageThreadLoop* This = (startMessageThreadLoop*)Param;
return This->ThreadStart();
}
DWORD ThreadStart(void)
{
MessageBox(hWnd, L"ThreadStart", L"ThreadStart", 0);
//create message loop for buttons
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
//translate and send messages
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void startMyThread()
{
MessageBox(hWnd, L"startMyThread", L"startMyThread", 0);
DWORD ThreadID;
CreateThread(NULL, 0, StaticThreadStart, (void*) this, 0, &ThreadID);
char szTest[100];
printf(szTest, "%d", ThreadID);
MessageBox(hWnd, LPCWSTR(szTest), L"ThreadIDBaby", 0);
}
};
Starting the thread
startMessageThreadLoop ThreadLoopInstance;
ThreadLoopInstance.startMyThread();
Creating the window
vidUploader.cbSize = sizeof(WNDCLASSEX);
vidUploader.style = CS_HREDRAW | CS_VREDRAW;
vidUploader.lpfnWndProc = WndProc;
vidUploader.cbClsExtra = 0;
vidUploader.cbWndExtra = 0;
vidUploader.hInstance = hUpload;
vidUploader.hIcon = LoadIcon(hUpload, MAKEINTRESOURCE(IDI_P2GOVIDEOUPLOADER20));
vidUploader.hCursor = LoadCursor(NULL, IDC_ARROW);
vidUploader.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
vidUploader.lpszMenuName = MAKEINTRESOURCE(IDC_P2GOVIDEOUPLOADER20);
vidUploader.lpszClassName = (LPCWSTR)(L"UploadVideo");
vidUploader.hIconSm = LoadIcon(wcexUpload.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&vidUploader);
hInst = hUpload; // Store instance handle in our global variable
hWnd = CreateWindow((LPCWSTR)(L"UploadVideo"), (LPCWSTR)(L"Upload Video's"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hUpload, NULL);
Handle Button
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
if (LOWORD(wParam) == IDC_SELECT_VIDEO) {
MessageBox(hWnd, L"Heeey", L"Hoi", 0);
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
Creating buttons & show Window
SelectVideoBTN = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"Select Video's", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
460, // y position
100, // Button width
25, // Button height
hWnd, // Parent window
(HMENU)IDC_SELECT_VIDEO, // Assign appropriate control ID
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
UploadBTN = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"Upload", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
390, // x position
460, // y position
100, // Button width
25, // Button height
hWnd, // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
RECT rect = { 0, 0, uploadWNDWidth, uploadWNDHeight };
AdjustWindowRect(&rect, GetWindowLong(hWnd, GWL_STYLE), FALSE);
SetWindowPos(hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE);
if (!hWnd)
{
MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
return 1;
}
MSG msg;
// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
//nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd,
nCmdShowUpload);
UpdateWindow(hWnd);
I believe that I'm doing everything that I have to in order to get the buttons to work, I have a message loop in a thread, I'm registering & handling the buttons and window, what am I missing?
The message queue of a window is linked to the thread in which the window was created. The message loop must be processed in the same thread.

WinAPI create window + child windows, process a button press?

I'm new to WinApi and I'm looking to create a simple window inside my program containing a blank parent window and two smaller child buttons "button1" & "button2". with this button I'm hoping to change a bool value from false to true and visa versa, but nearly all the examples I have seen are quite hard to understand, it seems like you have to return an MSG value of some kind which I don't know how to process.
I have a pseudocode below of what I'm trying to do, I have left comments explaining what I want to do at each moment, am I going about it the right way?:
#include <windows.h>
static int buildwindow(){
MSG msg;
//create parent window
HWND hWnd = CreateWindow(TEXT("scrollbar"), TEXT("Parent"), WS_VISIBLE | WS_POPUP,
10, 10, 800, 500, NULL, NULL, NULL, NULL);
//create child window
HWND hWnd1 = CreateWindow(TEXT("button"), TEXT("button1"), WS_CHILD|WS_VISIBLE | WS_POPUP,
10, 10, 80, 25, hWnd, NULL, NULL, NULL);
//create child window2
HWND hWnd2 = CreateWindow(TEXT("button"), TEXT("button2"), WS_CHILD|WS_VISIBLE | WS_POPUP,
100, 100, 80, 25, hWnd, NULL, NULL, NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
ShowWindow(hWnd1, SW_SHOW);
UpdateWindow(hWnd1);
ShowWindow(hWnd2, SW_SHOW);
UpdateWindow(hWnd2);
//wait for buttonpress
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//return the buttonpress
return (int) msg.wParam;
}
int main(void)
{
//create window inside the buttonpress method
int buttonpress = buildwindow();
//check which button was pressed
if(buttonpress = button1){
//do something
}
elseif(buttonpress = button2){
//do something else
}
//finish
return(0);
}
The message loop (GetMessage) won't end until a WM_QUIT message arrives.
You need to implement callback functions for the button click events.
I suggest reading more on button messages here:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb775941(v=vs.85).aspx

Creating two overlapped win32 windows simulatenously c++

I tried to create two overlapped windows but only one popped up. I plan to use 1 window to handle the buttons and another separate window(not child) to show images that changes every 1 second. Is it possible? I tried to use 1 window to handle both but the buttons went missing and are unable to click because the program is busy running the display. And what parameter to set for the HINSTANCE for the second window?
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
HWND hWnd2;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 0,1000, 700, NULL, NULL, hInstance, NULL);
hWnd2= CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 0,1000, 700, NULL, NULL, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("\t Start Scanning\n"),
WS_VISIBLE | WS_CHILD | WS_BORDER,
810, 320, 150, 150,
hWnd, (HMENU) IDM_BEGIN, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("\t STOP \n"),
WS_VISIBLE | WS_CHILD | WS_BORDER,
810, 480, 150, 150,
hWnd, (HMENU) IDM_PERMASTOP, NULL, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
You are creating two overlapped windows, but you are calling ShowWindow() on only the first time. Simply call ShowWindow() on the other one as well.

Empty borderless window not showing?

I'm trying to use the following code to show an empty border-less window, but no windows appear at all. I followed the documentation:
HWND hWnd = CreateWindowEx(WS_EX_TOPMOST,NULL,NULL,WS_POPUP,0,0,1000,1000,NULL,NULL,NULL,NULL);
ShowWindow(hWnd, SW_SHOW);
HWND hWnd = CreateWindowEx(WS_EX_TOPMOST, L"STATIC", NULL, WS_POPUPWINDOW, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
ShowWindow(hWnd, SW_SHOW);