When I add a menubar to a window, the window didn't resize accordingly because the top portion is hidden by the menubar. I want to resize the window while taking account of menubar's height. This is what I tried.
/* g++ test.cpp -o test -Wl,-subsystem,windows */
#include <Windows.h>
#define ID_OPEN 0
#define ID_EXIT 1
#define ID_ABOUT 2
const int width = 500;
const int height = 400;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szWndClassName[] = TEXT("hellowin");
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
//Step 1: Registering the Window Class
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szWndClassName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program only works in Windows NT or greater!"), TEXT("Hey dude!"), MB_OK | MB_ICONERROR);
return 1;
}
// Step 2: Creating the Window
hWnd = CreateWindow(szWndClassName, /* window class name */
TEXT("Hey!"), /* window title (or caption) */
WS_OVERLAPPEDWINDOW, /* window style */
CW_USEDEFAULT, /* initial x position */
CW_USEDEFAULT, /* initial y position */
width, /* initial window width */
height, /* initial window height */
NULL, /* parent window handle */
NULL, /* window menu handle */
hInstance, /* program instance handle */
NULL); /* creation parameters */
if (hWnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
// Step 3: The Message Loop (heart)
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
// Step 4: the Window Procedure (brain)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HMENU hMenuBar = CreateMenu();
HMENU hFile = CreatePopupMenu();
HMENU hHelp = CreatePopupMenu();
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hFile, "File");
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR) hHelp, "Help");
AppendMenu(hFile, MF_STRING, ID_OPEN, "Open");
AppendMenu(hFile, MF_STRING, ID_EXIT, "Exit");
AppendMenu(hHelp, MF_STRING, ID_ABOUT, "About");
SetMenu(hWnd, hMenuBar);
PMENUBARINFO pmbi;
GetMenuBarInfo(hWnd, OBJID_MENU, 0, pmbi);
RECT menuRect;
RECT windRect;
GetWindowRect(pmbi->hwndMenu, &menuRect);
GetWindowRect(hWnd, &windRect);
int width = menuRect.right - menuRect.left;
int height = (menuRect.bottom - menuRect.top) + (windRect.bottom - windRect.top);
SetWindowPos(hWnd,
0,
0,
0,
width,
height,
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
DrawText(hdc, TEXT("Hello World!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
I tried to retrieve rectangles of both menubar and the window and calculate the new dimension like this
int width = menuRect.right - menuRect.left;
int height = (menuRect.bottom - menuRect.top) + (windRect.bottom - windRect.top);
Unfortunately the code crashes. I have no idea which part I did wrong. Any ideas?
pmbi is an uninitialised pointer variable. Passing it to GetMenuBarInfo is therefore the likely cause of your crash. If that doesn't crash, then attempting to access pmbi->hwndMenu probably will.
Instead, you want:
MENUBARINFO mbi;
mbi.cbSize = sizeof (mbi); // see documentation
GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi);
...
which tells GetMenuBarInfo to fill in the (stack-based) variable mbi.
Then replace pmbi->hwndMenu with mbi.hwndMenu and that should fix your problem.
Related
When I build the program in visual studio It takes a long time to build and does not display properly, during this proccess it loads and unloads lots of what appears to be dll files in the console. If I remove the one line that starts with CreateWindowW(L"EDIT" the program will run perfectly. I have read through the documentation and I cant find what is wrong with it. Any help is appreciated.
Here is full code
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include<iostream>
#define file_menu_new 1
#define help_menu 2
#define file_menu_open 3
#define file_menu_exit 4
void AddMenus(HWND hwind);
HMENU hMenu;
void AddControls(HWND hwnd);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,_In_ PSTR szCmdLine, _In_ int iCmdShow)
{
// 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;
//regesters class above with operateing system
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 | WS_VISIBLE, // Window style
// Size and position
500, 200, 800, 500,//WS_DEFAULT OR SOMETHING LIKE THAT
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, iCmdShow);
// 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_COMMAND:
{
switch (wParam)
{
case file_menu_new:
MessageBeep(MB_OK);//this creates a sound
break;
case file_menu_exit:
DestroyWindow(hwnd);
break;
case file_menu_open:
MessageBeep(MB_ICONINFORMATION);
default:
break;
}
}
case WM_CREATE:
{
AddControls(hwnd);
AddMenus(hwnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
break;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void AddMenus(HWND hwind)
{
hMenu = CreateMenu();//main menu bar
HMENU hFileMenu = CreateMenu();//this is a drop down menu for the file part of main menu
//AppendMenu(hMenu, MF_STRING, 1, L"File");//1 is the identity of this main menu
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, L"File");//this is how you make it pop up another menu
AppendMenu(hFileMenu, MF_STRING, file_menu_new, L"New");//adds stuff to hFileMenu with the id of 1
AppendMenu(hFileMenu, MF_STRING, file_menu_open, L"Open");//adds stuff to hFileMenu with the id of 3
AppendMenu(hFileMenu, IMFT_SEPARATOR, NULL, NULL);//creates a seperator or a line under open
AppendMenu(hFileMenu, MF_STRING, file_menu_exit, L"Exit");
AppendMenu(hMenu, MF_STRING, help_menu, L"Help");//2 is the identity of this main menu
//sets the hMenu to the hwind menu or the main menu
SetMenu(hwind, hMenu);
}
void AddControls(HWND hwnd)
{
CreateWindowW(L"static", L"Enter Text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER | WS_EX_TRANSPARENT,
200, 100, 100, 50, hwnd, NULL, NULL, NULL);
CreateWindowW(L"EDIT", L"Enter Text here: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER,
200, 160, 100, 50, hwnd, NULL, NULL, NULL);
}
Add wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); and remove WM_PAINT. If you don't set a class background you need to handle WM_ERASEBKGND or otherwise validate the background color painting.
I am a little new to C++, so I am starting out with a text editor program. I am developing this project in NetBeans IDE. Currently the application is all in the main source file. When I compile and run the project, I get no errors and the project proceeds to function.
However, I have some sort of error or bug that lies within the application as it is running. This bug is associated with the Edit Control and the GetWindowText() method. The problem is located in the saveFile() function. What I am making of the GetWindowText() function is to test to see if I can retrieve text from the Edit Control and use it for my needs. I tried to emulate it through a simple MessageBox() function, and I got nothing.
Source code [FULL]:
/*
* File: main.cpp
* Author: CA1K
*
* Created on November 1, 2015, 9:58 PM
*/
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
// [ PROGRAM PROCEDURES ]
//=========================================================
/*Really what these are used for is to address conditions to
*the WS_COMMAND case, these are registered as integers
*/
#define IDC_MAIN_EDIT 0//edit ID
#define EXIT_PROC 1//the exit procedure
#define ABOUT_PROC 2//the trigger for the "about" window
#define CLONE_PROC 3//spawn a new window
#define SAVE_PROC 4//save procedure
#define OPEN_PROC 5//copy procedure
//=========================================================
// [ DEVELOPER FRIENDLY VARIABLES ]
//=========================================================
const char g_szClassName[] = "CPadx1"; //window class name
const char g_Title[] = "CPad"; //window title
const char g_About[] = "CPad is a program developed by CA1K. It is entirely made from the win32 API. For more programs, go to ca1k.xkotto.com.";
int dim = 600;//window dimensions(square)
TCHAR buffer[512];
//=========================================================
// [ OBJECT BUILDING ]
//=========================================================
void makeMenu(HWND hwnd){
HMENU hMenubar;
HMENU hMenu;
HMENU hMenu2;
hMenubar = CreateMenu();
hMenu = CreateMenu();
hMenu2 = CreateMenu();
AppendMenuW(hMenu, MF_STRING, SAVE_PROC, L"&Save/Save as");
AppendMenuW(hMenu, MF_STRING, OPEN_PROC, L"&Open file");
AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenuW(hMenu, MF_STRING, CLONE_PROC, L"&New Window");
AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenuW(hMenu, MF_STRING, ABOUT_PROC, L"&About");
AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)hMenu, L"&File");
AppendMenuW(hMenu2, MF_STRING, EXIT_PROC, L"&Exit");
AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)hMenu2, L"&Config");
SetMenu(hwnd, hMenubar);
}
void dispWnd(HWND hwnd){//this function spawns a new window
HINSTANCE hInstance;
HWND newChild = CreateWindowEx(0, g_szClassName, g_Title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, dim, dim, hwnd, NULL, hInstance, NULL);
HWND GetParent(HWND hwnd);
ShowWindow(newChild, 1);
UpdateWindow(newChild);
}
void makeEdit(HWND hwnd, HWND hEdit){//this function creates the edit
HINSTANCE hInstance;
RECT rect;
int pwidth;
int pheight;
if(GetWindowRect(hwnd, &rect))
{
pwidth = rect.right - rect.left;
pheight = rect.bottom - rect.top;
}
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",
WS_CHILD|WS_VISIBLE|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_MULTILINE,
0,0,pwidth,pheight,hwnd,(HMENU)IDC_MAIN_EDIT,
hInstance,NULL);
}
void saveFile(HWND hEdit){
GetWindowText(hEdit, buffer, 512);
MessageBox(NULL, buffer, "Test", MB_ICONINFORMATION);
}
//=========================================================
// [ SOFTWARE PROCESSING ]
//=========================================================
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND winEdit;
switch(msg)
{
/*WINDOW ACTIONS*/
case WM_CREATE:{//on window creation
makeMenu(hwnd);
makeEdit(hwnd,winEdit);
}
break;
case WM_SIZE:
makeEdit(hwnd,winEdit);
break;
case WM_COMMAND://window actions
switch(LOWORD(wParam))
{
case ABOUT_PROC:
MessageBox(NULL, g_About, "About", MB_ICONINFORMATION);
break;
case EXIT_PROC:
PostQuitMessage(0);//exit program
break;
case CLONE_PROC:
dispWnd(hwnd);
break;
case SAVE_PROC:
saveFile(winEdit);
break;
}
break;
case WM_CLOSE://on window close
DestroyWindow(hwnd);
break;
case WM_DESTROY://on window destroy
PostQuitMessage(0);
break;
default://default method
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
g_Title,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, dim, dim,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
//=========================================================
I am questioning whether I have the scopes wrong, or something else. Feed back would be much appreciated.
-CA1K
You need to make winEdit a static variable. This is because you use it in more than one message, like WM_CREATE and WM_COMMAND. Then, you need to pass a pointer to an HWND to your makeEdit function:
makeEdit(hwnd, &winEdit);
So your overall window procedure should look like this:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND winEdit;
switch(msg)
{
/*WINDOW ACTIONS*/
case WM_CREATE:{//on window creation
makeMenu(hwnd);
makeEdit(hwnd, &winEdit);
}
break;
case WM_SIZE:
makeEdit(hwnd,winEdit);
break;
case WM_COMMAND://window actions
switch(LOWORD(wParam))
{
case ABOUT_PROC:
MessageBox(NULL, g_About, "About", MB_ICONINFORMATION);
break;
case EXIT_PROC:
PostQuitMessage(0);//exit program
break;
case CLONE_PROC:
dispWnd(hwnd);
break;
case SAVE_PROC:
saveFile(winEdit);
break;
}
break;
case WM_CLOSE://on window close
DestroyWindow(hwnd);
break;
case WM_DESTROY://on window destroy
PostQuitMessage(0);
break;
default://default method
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
I have two icons (.ico files). A big 32x32 one and another small 16x16.
I'm trying to set the hIcon of my WNDCLASSEX to be the big one, and hIconSm to the smaller one. Yet I cannot for the life of me figure out how to do that! I first tried LoadIcon:
wndclass.hIcon = LoadIcon(instance, MAKEINTRESOURCE(IDI_SKELETON));
wndclass.hIconSm = LoadIcon(instance, MAKEINTRESOURCE(IDI_SKELETON_SM));
It always loads the same icon for both the top window bar and the taskbar. Same thing with LoadImage.
Here's all the codes:
Resource.h
#define IDI_SKELETON 1000
#define IDI_SKELETON_SM 1001
Skeleton.rc
#include "Resource.h"
IDI_SKELETON ICON "Skeleton.ico"
IDI_SKELETON_SM ICON "Skeleton_sm.ico"
WinMain.cpp
#include <windows.h>
#include "Resource.h"
LRESULT CALLBACK
HandleEvent(HWND window,
UINT message,
WPARAM wparam,
LPARAM lparam)
{
switch(message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC dc;
RECT rect;
dc = BeginPaint(window, &ps);
GetClientRect(window, &rect);
DrawText(dc, TEXT("This is a test window"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(window, &ps);
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProc(window, message, wparam, lparam);
}
int CALLBACK
WinMain(HINSTANCE instance,
HINSTANCE previous,
LPSTR cmd,
int cmdshow)
{
WNDCLASSEX wndclass;
TCHAR classname[] = TEXT("24HoursClass");
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = HandleEvent;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = instance;
wndclass.hIcon = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_SKELETON), IMAGE_ICON,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
wndclass.hIconSm = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_SKELETON_SM), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = classname;
RegisterClassEx(&wndclass);
HWND window = CreateWindowA(classname, "24 Hours",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, instance, 0);
MSG msg;
while(GetMessage(&msg, window, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
What am I missing?
Any help is appreciated!
Hello all I have been trying to paint to my child window outside of WM_PAINT and Instead of painting on the child window it paints off of the window onto the screen I think it may be because of the location of x and y but shouldn't point (0,0) be the top left of the child window not of my actual screen?
Here is what the code I wrote to try to paint onto the child window:
#pragma warning(disable:4996)
#pragma comment(lib, "Ws2_32.lib")
#include <Windows.h>
#define WIDTH 800
#define HEIGHT 600
#define CLASS_NAME "Class"
#define IDC_MAIN_EDIT 101
#define IDC_WINDOW 102
int x = 0, y = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void print_line(HWND hwnd, char *Msg);
void Println();
int Run();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = { 0 };
MSG msg;
HWND hwnd = NULL;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = CLASS_NAME;
wcex.hInstance = hInstance;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBoxA(NULL, "Failed to register class", "Error", MB_OK | MB_ICONERROR);
return -1;
}
hwnd = CreateWindow(CLASS_NAME //Name of the window class
, CLASS_NAME//Title of the window
, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN// the window style
, 0 //x Postition of the window
, 0// y position of the windpo
, WIDTH, HEIGHT, // Width and Height
NULL,//Parent window(we have no parent window)
NULL,//Menu(we are not using menu's)
hInstance,//application handle
NULL);//Creates the window
if (!hwnd)
{
MessageBoxA(NULL, "Failed to register class", "Error", MB_OK | MB_ICONERROR);
return -2;
}
ShowWindow(hwnd, nCmdShow);
return Run();
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND hEdit = NULL;
HWND hWindow = NULL;
#define Print(msg2) print_line(hWindow, msg2)
switch (msg)
{
case WM_CREATE:
hWindow = CreateWindowEx(WS_EX_CLIENTEDGE, "Window", "",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | WS_CLIPSIBLINGS,
0, 0, WIDTH, HEIGHT - 25, hwnd, (HMENU)IDC_WINDOW, GetModuleHandle(NULL), NULL);
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL,
0, 535, WIDTH, 25, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
Print("Hello");
break;
default:
return (DefWindowProc(hwnd, msg, wParam, lParam));
}
}
int Run()
{
MSG msg = { 0 };
WSAData wsa;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsa) != 0) return -1;
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
void print_line(HWND hwnd, char *Msg)
{
HDC hdc;
hdc = GetDC(hwnd);
TextOut(hdc,
x,
y,
Msg,
strlen(Msg));
ReleaseDC(hwnd, hdc);
}
void Println()
{
x = 0;
y += 20;
}
Yes I know there are other questions concerning this topic but none of them seemed to answer my question or address any of the problems I have been experiencing while trying to paint on the child window.
It Seems to me you create your windows in WndProc, but they do not get returned, so both windows created in WndProc end up being NULL when WM_CREATE returns (AS the are only declared in WndProc).
Perhaps you need to set these both to globals, the use for example GetDC(hEdit) to draw to them. Overall it still looks like an odd bit of code.
It seems to me that you want to write text to the edit control you created with id=IDC_MAIN_EDIT by manually drawing the text into the control?
Try
case WM_COMMAND:
//Print("Hello");
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT); // get handle to edit window
if (hEdit != NULL) // did we get a handle to the edit window?
{
int len = GetWindowTextLength(hEdit);
SendMessage(hEdit , EM_SETSEL, len, len); // select end of contents
SendMessage(hEdit , EM_REPLACESEL, 0, (LPARAM)"Hello"); // replace end with new textt
}
break;
and the edit control will draw the text for you.
If you want to manually write the text to the window created by you modify the Print macro as follows:
#define Print(msg2) print_line(hwnd, msg2)
Look At this code and please tell me why when I compile it I see a blank white screen:
#include <windows.h>
#include <fstream.h>
#include <stdlib.h>
static char g_szClassName[] = "TEST";
static HINSTANCE g_hInst = NULL;
int savenumber = 1;
char savestring[] = "abc";
HWND hwnd;
HDC hdcWindow;
PAINTSTRUCT ps;
RECT rc;
//HBITMAP mario1,mario2,mario3,mario4,mario5,mario6,
// block1,block2,block3,scene1,scene1mask;
HBITMAP scene1;
BITMAP bm;
LRESULT CALLBACK
WndProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
HBITMAP g_hbitmap = NULL;
switch(nMsg)
{
case WM_CREATE:
g_hbitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL),
"C:\\Users\\Onwer\\Desktop\\Cpp code Initiate\\Jacob GRAPIC#3 cpp renewal!\\G3-Images\\scene.bmp",
IMAGE_BITMAP,
640,
320,
LR_LOADFROMFILE);
/*
mario1 = LoadBitmap(g_hInst, "MARIO1BMP");
mario2 = LoadBitmap(g_hInst, "MARIO2BMP");
mario3 = LoadBitmap(g_hInst, "MARIO3BMP");
mario4 = LoadBitmap(g_hInst, "MARIO4BMP");
mario5 = LoadBitmap(g_hInst, "MARIO5BMP");
mario6 = LoadBitmap(g_hInst, "MARIO6BMP");
block1 = LoadBitmap(g_hInst, "BLOCK1BMP");
block2 = LoadBitmap(g_hInst, "BLCOK2BMP");
block3 = LoadBitmap(g_hInst, "BLOCK3BMP");
scene1 = LoadBitmap(g_hInst, "SCENE1BMP");
scene1mask = LoadBitmap(g_hInst, "SCENE1MASKBMP");
*/
scene1 = LoadBitmap(g_hInst, "SCENE1BMP");
break;
case WM_TIMER:
break;
case WM_PAINT:
hdcWindow = BeginPaint(hwnd, &ps);
GetClientRect (hwnd, &rc);
drawScene (hdcWindow);
//DrawText(hdcWindow,"This Is a Test!", -1, &rc,
//DT_SINGLELINE | DT_TOP | DT_TOP );
EndPaint(hwnd, &ps);
break;
case WM_COMMAND:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
/*
DeleteObject(mario1);
DeleteObject(mario2);
DeleteObject(mario3);
DeleteObject(mario4);
DeleteObject(mario5);
DeleteObject(mario6);
DeleteObject(block1);
DeleteObject(block2);
DeleteObject(block3);
*/
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, nMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
ofstream SaveFile ("save.txt");
SaveFile << savenumber << '\n' << savestring;
WNDCLASSEX WndClass;
HWND hwndMain;
MSG Msg;
g_hInst = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = 0;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = g_szClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass))
{
MessageBox(0, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"TEST",
WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, CW_USEDEFAULT, 677, 358,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 500,
NULL, NULL, g_hInst, NULL);
if(hwnd == NULL)
{
MessageBox(0, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
I need to know why LoadImage doesn't display the picture designated. Is it not even supposed to? And if its not supposed t: tell me what function that goes with loadImage I should use, that is part of Windows.h in C++. I am using the Dev-C++ compiler.
All LoadImage does it loads an image, nothing else. If you want your application to draw an image in a window you have to do it yourself.
The contents of drawScene() were commented out (since removed in an edit) and your WM_PAINT handler doesn't perform any drawing operations. If your bitmap was successfully loaded you will need to do something like below when you handle the WM_PAINT message.
hdcMemory = CreateCompatibleDC(hdcWindow);
HGDIOBJ oldBitmap = SelectObject(hdcMemory, g_hbitmap);
BitBlt(hdcWindow, 0, 0, 640, 320, hdcMemory, 0, 0, SRCCOPY);
SelectObject(hdcMemory, oldBitmap);
DeleteDC(hdcMemory);