// <^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^
// * Shawn McBroom *
// * Gor435@gdnmail.net *
// * 1/24/2005 *
// <^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^>|<^
#define WIN32_LEAN_AND_MEAN
#define ID_FILE_EXIT 0
#define ID_FILE_NEW 1
#define ID_HELP_ABOUT 1000
#define PD_ICON "Battle Paddles.ico"
#include <windows.h> // include our windows header of course
#include <assert.h>
const char wndclass[] = "The Window Class";// declair our window class name
const char wndname[]= "Battle Paddles"; // The title text for our window
// prototype our windows procedure funtion which handles messages
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE wndins, HINSTANCE windpins, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;// wc will be our WNDCLASSEX structure object
HWND hWnd; //window
MSG msg; // messages
wc.cbSize = sizeof (WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = wndins;
wc.hIcon = LoadIcon(NULL, PD_ICON);
wc.hIconSm =(HICON) LoadImage(NULL, "Battle Paddles.ico", IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR | LR_LOADFROMFILE);
wc.hCursor = LoadCursor(NULL, IDC_HAND);
wc.lpszMenuName = NULL;
wc.lpszClassName = wndclass;
wc.hbrBackground = (HBRUSH)(2);
if(!RegisterClassEx(&wc)) // if the window didnt register right you want to display a
// message box that explains with ok button when clicked close
// the program
{
MessageBox(NULL, "Window Registration Failed!", " UH OH ", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, wndclass, wndname, WS_OVERLAPPEDWINDOW, // make hWnd equal too CreateWindowEx funtion
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, wndins, NULL);
if(hWnd == NULL) // if the window was not properly created post message and quit
{
MessageBox(NULL, "Failed to create window", " UH OH ", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nCmdShow);// we have to show the window to the screen so you can see it
UpdateWindow(hWnd);// update the window
while(GetMessage(&msg, NULL, 0, 0) > 0)//message loop
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)// windows procedure funtion
{
switch(msg)
{
case WM_CREATE: // when the window is created do this
{
HMENU hMenu, hSubMenu, hsubmenu;
hMenu = CreateMenu();
hSubMenu = CreatePopupMenu();
hsubmenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_NEW, "&New");
AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu,"&File");
AppendMenu(hsubmenu, MF_STRING, ID_HELP_ABOUT, "&About");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hsubmenu,"&Help");
SetMenu(hWnd, hMenu);
}
break;
case WM_COMMAND:// when something on one of the menus are selected
{
switch(LOWORD(wParam))// we need to figure out which menu option was selected
{
case ID_FILE_EXIT:// if the exit option was chosen
{
PostQuitMessage(WM_QUIT);// quit the program
break;
}
case ID_FILE_NEW:// if the new option was chosen
{
break;
}
case ID_HELP_ABOUT://if help option was chosen
{
MessageBox(NULL, " Spark Software\n\n Shawn McBroom\n\nE-mail me at gor435@gdnmail.net ", "About", MB_ICONASTERISK | MB_OK);
break;
}
}
break;
}
case WM_CLOSE://if user chooses to close the window
{
DestroyWindow(hWnd);//get rid of the window
break;
}
case WM_DESTROY:// when you get rid of the window you need to stop the program
{
PostQuitMessage(0);//quit the program
break;
}
case WM_COMPACTING:// this gets sent to all top level programs when the system is low on memory
{
MessageBox(NULL, "Oh, your system is low on memery this program should close", "Low Memory", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
case WM_LBUTTONDOWN:
{
HBITMAP hbitmap;
HDC hdc, bhdc;
tagPAINTSTRUCT bm;
tagBITMAPINFO bmi;
hdc = GetWindowDC(hWnd);
hbitmap = (HBITMAP)LoadImage(NULL, "background.bmp", IMAGE_BITMAP, 100, 100, LR_LOADFROMFILE | LR_DEFAULTCOLOR );
if(hbitmap == NULL)
{
MessageBox(NULL, "Bitmap load failed :(", "FAILURE", MB_ICONEXCLAMATION | MB_OK);
}
else
{
MessageBox(NULL, "Bitmap load success :)", "SUCCESS!!", MB_ICONEXCLAMATION | MB_OK);
}
//bhdc = GetDC((HWND)hbitmap);
//bhdc = (HDC)SelectObject(GetDC((HWND)hbitmap), hbitmap);
GetDIBits(bhdc, hbitmap, 1, 100, NULL, &bmi, DIB_PAL_COLORS);
SetDIBitsToDevice(bhdc, 30, 30, 100, 100, 100, 100, 1, 100, NULL, &bmi, DIB_PAL_COLORS);
//assert(bhdc != 0);
BeginPaint(hWnd, &bm);
BitBlt(hdc, 10, 10, 100, 100, bhdc, 0, 0, SRCCOPY);
EndPaint(hWnd, &bm);
UpdateWindow(hWnd);
ReleaseDC(hWnd, hdc);
break;
}
default:
return DefWindowProc(hWnd, msg, wParam, lParam);//what to do if you get a message we are not looking for
}
return 0;
}
Bitmap Display Problem
I have tried everthing with this code i can not get my bitmap to display it loads properly but it doesnt display :(
its coded in c++
and yes i do want to be able to click the window to display it
any ideas??
You need to do the bitmap drawing in the WM_PAINT message. What you can do in your WM_LBUTTONDOWN handler is load the bitmap, saving the HBITMAP somewhere safe, and force an update (InvalidateRect() I think). Then, add a WM_PAINT handler, and do the bitmap drawing there using the saved HBITMAP. The WM_PAINT handler can check the saved bitmap handle, and if it's not NULL, draw the bitmap.
According to MSDN, "an application should not call BeginPaint except in response to a WM_PAINT message".
Also, since your window can become corrupted by moving/resizing/insert-reason-here, you would need to redraw your bitmap any time you received a WM_PAINT message, anyway.
According to MSDN, "an application should not call BeginPaint except in response to a WM_PAINT message".
Also, since your window can become corrupted by moving/resizing/insert-reason-here, you would need to redraw your bitmap any time you received a WM_PAINT message, anyway.
ok i may have misunderstood your post but when i do the WM_PAINT it still didnt do anything :(
Are you using InvalidateRect() (I think that's it) in your mouse handle? That will get a WM_PAINT message sent to you.
Ok maybe I wasnt the one confused because everytime the window refreshes it sends a WM_PAINT message. So using the InvalidateRect() function will not help me to get a WM_PAINT message.
yes but they never said it "can not call" it "should not call" because it is the only time the windows procedure should draw to the window but no body ever said it could not be done with a click :)
Quote:According to MSDN, "an application should not call BeginPaint except in response to a WM_PAINT message".
yes but they never said it "can not call" it "should not call" because it is the only time the windows procedure should draw to the window but no body ever said it could not be done with a click :)
Quote:Original post by Gor435
Ok maybe I wasnt the one confused because everytime the window refreshes it sends a WM_PAINT message. So using the InvalidateRect() function will not help me to get a WM_PAINT message.
No you were right the first time, you are the one confused. InvalidateRect() should eventually call a WM_PAINT message.
Edit: I don't think you need the BeginPaint and Endpaint functions. In this case I don't see what they do since they are normally used to return a HDC which you already do with the GetDC() function. I think the problem with your code is no paint message is being generated. With the InvalidateRect function it should work.
You can draw outside of the WM_PAINT message anytime you want (but not using BeginPaint/EndPaint). However, when the WM_PAINT message is processed, anything you've drawn will be lost. One of the messages sent when the system determines that a redraw is necessary is a WM_ERASEBKGND. The default message handler will clear the background of your window when it processes that message. When that happens, your image is gone.
The correct way to do what you want to do is set a flag and issue an InvalidateRect() when the WM_LBUTTONDOWN occurs. Then add a WM_PAINT handler that draws your bitmap when the flag is set.
And I don't think Microsoft said "should not" simply because they didn't want you to become an Uber God and know the deep, dark mysteries of the GDI. They said it because either it won't work, or it is not in your best interest to do so.
The correct way to do what you want to do is set a flag and issue an InvalidateRect() when the WM_LBUTTONDOWN occurs. Then add a WM_PAINT handler that draws your bitmap when the flag is set.
And I don't think Microsoft said "should not" simply because they didn't want you to become an Uber God and know the deep, dark mysteries of the GDI. They said it because either it won't work, or it is not in your best interest to do so.
Ok here is what MSDN says
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_88ac.asp
really i dont think i was all that confused reads pretty clearly
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_7ano.asp
which I do not see how this will help if i am using BitBlt
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_7b78.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0fzo.asp
Anyways don't worry about it I got it to work
Quote:
WM_PAINT
The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_88ac.asp
really i dont think i was all that confused reads pretty clearly
Quote:
InvalidateRect
The InvalidateRect function adds a rectangle to the specified window's update region. The update region represents the portion of the window's client area that must be redrawn.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_7ano.asp
which I do not see how this will help if i am using BitBlt
Quote:
BeginPaint
The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_7b78.asp
Quote:
BitBlt
The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0fzo.asp
Anyways don't worry about it I got it to work
Also on the BeginPaint page you linked:
Also on the InvalidateRect page you linked:
You've got to read the entire page, not just the short description.
At any rate, congratulations on getting it to work.
Quote:The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region. The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window.
An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to the EndPaint function.
Also on the InvalidateRect page you linked:
Quote:The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.
You've got to read the entire page, not just the short description.
At any rate, congratulations on getting it to work.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement