Every time I try loadimage I get a conversion error....I've tried about 20 different thiings and can't get it...:mad: does someone have a sample laying around that uses LoadImage()?
Printable View
Every time I try loadimage I get a conversion error....I've tried about 20 different thiings and can't get it...:mad: does someone have a sample laying around that uses LoadImage()?
This is the code I wrote for a dialog(testing purpose) in a control button clicked function.
Later, I'm going to do a SDI to make use of the CFileDialog to load the bitmap.
If u are going to redraw, u have to modify a bit.Code://The code below, loads the bitmap into a mem DC
//then from the memory DC blit to the dialog window.
//** Create a paint DC from the dialog window
CClientDC clientDC(this);
//Win32 code below
//char Path[]="E:\\svbitmaps\\sv24bit.bmp";
//Change the Path and file to the one u want
char Path[]="E:\\svbitmaps\\sv8bitbig.bmp";
HANDLE hImage=LoadImage(NULL,Path,IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);
if (hImage==NULL){
CHAR szBuf[80];
DWORD dw = GetLastError();
sprintf(szBuf, "%s failed: GetLastError returned %u\n",
"LoadImage", dw);
//Don't be mistaken; This is MFC version of MessageBox
MessageBox(szBuf, "Error", MB_OK);
OnOK();
}
//Structure to hold information about the Bitmap
BITMAP Bitmap;
//Holds the dimensions of the Bitmap
SIZE ImageSize;
//Get info about the bitmap
GetObject(hImage, sizeof(Bitmap), &Bitmap);
ImageSize.cx=Bitmap.bmWidth;
ImageSize.cy=Bitmap.bmHeight;
//MFC code starts here
//Create compatible memory device context
CDC memDC;
memDC.CreateCompatibleDC(&clientDC);
// ** Select it into our memory device context
memDC.SelectObject(CBitmap::FromHandle((HBITMAP) hImage));
//do blitting here.
clientDC.BitBlt(0,0,ImageSize.cx,ImageSize.cy,&memDC,0,0,SRCCOPY);
//Delete DC for the Bitmap
DeleteObject(hImage);
perfect! thanks soo much! :cool:
Too bad I just found out my code is not perfect.
I CAN'T do a OnPaint(WM_PAINT). If I tried to call the above routine, it hung my Win98.
Nvm, here's the solution.:DCode in blue is what I had changed in order to call it in OnPaint function without crashingCode:void CLoadBitmapsvDlg::OnDraw()
{
// TODO: Add your control notification handler code here
//The code below, loads the bitmap into a mem DC
//then from the memory DC blit to the dialog window.
//** Create a paint DC from the dialog window
CPaintDC paintDC(this);
//Win32 code below
//char Path[]="E:\\svbitmaps\\sv24bit.bmp";
char Path[]="E:\\svbitmaps\\sv8bitbig.bmp";
HANDLE hImage=LoadImage(NULL,Path,IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);
if (hImage==NULL){
CHAR szBuf[80];
DWORD dw = GetLastError();
sprintf(szBuf, "%s failed: GetLastError returned %u\n",
"LoadImage", dw);
//Don't be mistaken; This is MFC version of MessageBox
MessageBox(szBuf, "Error", MB_OK);
OnOK();
}
//Structure to hold information about the Bitmap
BITMAP Bitmap;
//Holds the dimensions of the Bitmap
SIZE ImageSize;
//Get info about the bitmap
GetObject(hImage, sizeof(Bitmap), &Bitmap);
ImageSize.cx=Bitmap.bmWidth;
ImageSize.cy=Bitmap.bmHeight;
//MFC code starts here
//Create compatible memory device context
CDC memDC;
memDC.CreateCompatibleDC(&paintDC);
// ** Select it into our memory device context
memDC.SelectObject(CBitmap::FromHandle((HBITMAP) hImage));
//do blitting here.
paintDC.BitBlt(0,0,ImageSize.cx,ImageSize.cy,&memDC,0,0,SRCCOPY);
//Delete DC for the Bitmap
DeleteObject(hImage);
}
Steve, if u dun want to always load the bmp file for every WM_PAINT msg, u have to modify, so that it only load the bmp once and for all WM_PAINTs.;)
It's simple.
already modified :) Right now I only have 1 tiny problem...when I try more than 1 graphic, it only shows 1...
hDC = BeginPaint( ghWnd_Main, &ps );
clears the screen and draws on it...so the second image kind of clears the first...any way around this?
WM_PAINT will be fired when everything you drew is cleared and it needs repaint. BeingPaint(....) is used to get the handle to the device context when WM_PAINT is fired. It doesn't clear anything because it's already done. Make sure you aren't drawing your second bitmap on top of the other one (like the x any coordinates are same).
they're not the same :(
and by switching function call order I can show different pictures...thats why i figured something was clearing.
Steve:Are u doing a MFC or Win32 app?
I am doing a MFC app. How come u can use my code?:rolleyes:
U have to always delete hImage before u load a new file.Code:..........
HANDLE hImage=LoadImage(NULL,Path,IMAGE_BITMAP,
0,0,LR_LOADFROMFILE);
.........
........
DeleteObject(hImage);
.......
Win32...but yours was enough to get me to figure it out :)
Ignore my previous post
Maybe I didn't understand your problem.
Can u rephrase?
Are you doing exactly the same thing as what transcendental posted? It seems like he's only drawing one bitmap so I don't know if there's any other bitmap or anything else to erase. Can you post your code?
Let me just explain everything so no ones confused :)
I put all the code into a class...the class draws the image.
But when I try making 2, only 1 will show :( :confused:
they load different images at different spots to make sure they aren't just overlapping
heres the whole cpp file...sorry if its kind of sloppy...its a lot of code lumped into 1. (may not be the most efficient either.
EDIT
in WM_PAINT the two calls are commented...that was just part of testing, thats not my problem...:p
I haven't read your code yet. I'm not the one who requested it.
I think for every WM_PAINT msg, u have to call these 2 functions to load 2 bitmaps.
Hmm odd, it seems that if you call BeginPaint() twice, it effects the visibility of your contents. A quick solution would be to call BeginPaint(...) once when you get WM_PAINT message and then call graphics.paint() with the hdc you got your BeginPaint(...). Here's an example of working code:
PHP Code://Steve Mack
#include <windows.h>
HWND ghWnd_Main;
HINSTANCE ghInst;
HINSTANCE ghInst2;
class graphic
{
public:
int x;
int y;
char filename[50];
~graphic(){}
void Paint(HDC hDC);
BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,HPALETTE *phPalette );
HBITMAP CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent);
void SetFileName(char file[50]);
};
void graphic::SetFileName(char file[50])
{
strcat(filename, file);
}
BOOL graphic::LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap,HPALETTE *phPalette )
{
BITMAP bm;
*phBitmap = NULL;
*phPalette = NULL;
// Use LoadImage() to get the image loaded into a DIBSection
*phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
if( *phBitmap == NULL )
return FALSE;
// Get the color depth of the DIBSection
GetObject(*phBitmap, sizeof(BITMAP), &bm );
// If the DIBSection is 256 color or less, it has a color table
if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
{
HDC hMemDC;
HBITMAP hOldBitmap;
RGBQUAD rgb[256];
LPLOGPALETTE pLogPal;
WORD i;
// Create a memory DC and select the DIBSection into it
hMemDC = CreateCompatibleDC( NULL );
hOldBitmap = (HBITMAP)SelectObject( hMemDC, *phBitmap );
// Get the DIBSection's color table
GetDIBColorTable( hMemDC, 0, 256, rgb );
// Create a palette from the color tabl
pLogPal = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY)) );
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = 256;
for(i=0;i<256;i++)
{
pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
}
*phPalette = CreatePalette( pLogPal );
// Clean up
free( pLogPal );
SelectObject( hMemDC, hOldBitmap );
DeleteDC( hMemDC );
}
else // It has no color table, so use a halftone palette
{
HDC hRefDC;
hRefDC = GetDC( NULL );
*phPalette = CreateHalftonePalette( hRefDC );
ReleaseDC( NULL, hRefDC );
}
return TRUE;
}
HBITMAP graphic::CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent)
{
HDC hdcMem, hdcMem2;
HBITMAP hbmMask;
BITMAP bm;
GetObject(hbmColour, sizeof(BITMAP), &bm);
hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
hdcMem = CreateCompatibleDC(0);
hdcMem2 = CreateCompatibleDC(0);
SelectObject(hdcMem, hbmColour);
SelectObject(hdcMem2, hbmMask);
SetBkColor(hdcMem, crTransparent);
BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT);
DeleteDC(hdcMem);
DeleteDC(hdcMem2);
return hbmMask;
}
void graphic::Paint(HDC hDC)
{
HBITMAP hBitmap, hOldBitmap;
HPALETTE hPalette, hOldPalette;
BITMAP bm;
HDC hdc;
HBITMAP g_hbmMask;
HDC hMemDC;
if( LoadBitmapFromBMPFile( filename, &hBitmap, &hPalette ) )
{
hMemDC = CreateCompatibleDC( hDC );
GetObject( hBitmap, sizeof(BITMAP), &bm );
g_hbmMask = CreateBitmapMask(hBitmap, RGB(0, 0, 0));
GetObject( g_hbmMask, sizeof(BITMAP), &bm );
hOldBitmap = (HBITMAP)SelectObject( hMemDC, g_hbmMask );
hOldPalette = SelectPalette( hDC, hPalette, FALSE );
// RECT rcClient;
BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);
hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
hOldPalette = SelectPalette( hDC, hPalette, FALSE );
RealizePalette( hDC );
BitBlt( hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCPAINT );
SelectObject( hMemDC, hOldBitmap );
DeleteObject( hBitmap );
SelectPalette( hDC, hOldPalette, FALSE );
DeleteObject( hPalette );
}
}
graphic PIC;
graphic TEST;
//function prototypes
void SetFont(HWND hWnd, int iPointSize, const char *pcFontName); //(obviously) sets fonts of controls
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hDC;
switch(uMsg) {
case WM_CLOSE:
DestroyWindow(ghWnd_Main); // Destroy the main window
return 0;
case WM_DESTROY:
PostQuitMessage(0); // Quit the application
return 0;
case WM_CREATE:
return 0;
case WM_PAINT: //updates the pic everytime needed
{
hDC = BeginPaint( ghWnd_Main, &ps );
TEST.Paint(hDC);
PIC.Paint(hDC);
EndPaint(ghWnd_Main, &ps);
}
return 0;
case WM_COMMAND:
//if(LOWORD(wParam) == BN_CLICKED && (HWND)lParam == OPENABOUT) {
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam); // Not handled - let the system deal with it
}
//==================WINDOW CODE=========================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
ghInst = hInstance;
ghInst2 = hInstance;
WNDCLASSEX wcxMyClass;
wcxMyClass.cbSize = sizeof(WNDCLASSEX); // Size of structure in bytes
wcxMyClass.style = 0; // Extra style information
wcxMyClass.lpfnWndProc = WndProc; // Pointer to window procedure
wcxMyClass.cbClsExtra = 0; // Extra bytes in class definition
wcxMyClass.cbWndExtra = 0; // Extra bytes for each window
wcxMyClass.hInstance = hInstance; // Instance handle for the class
wcxMyClass.hIcon = NULL; // Default icon - use system
wcxMyClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the system arrow
wcxMyClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); // Background brush
wcxMyClass.lpszMenuName = NULL; // Menu name [MAKEINTRESOURCE(IDM_MAINMENU)] - none here
wcxMyClass.lpszClassName = "TESTCLASS"; // Class name
wcxMyClass.hIconSm = NULL; // Small icon
RegisterClassEx(&wcxMyClass); // Register the class
ghWnd_Main = CreateWindow("TESTCLASS", "Graphics Working", \
WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 423, 347, \
NULL, NULL, hInstance, NULL);
if(ghWnd_Main) {
// ADDITEM = CreateWindowEx(WS_EX_CLIENTEDGE, "Button", "Add", WS_CHILD | /*WS_DLGFRAME |*/ WS_VISIBLE, 209, 1, 66, 40, ghWnd_Main, NULL, hInstance, NULL);
PIC.x = 100;
PIC.y = 100;
PIC.SetFileName("test.bmp");
TEST.x = 0;
TEST.y = 0;
TEST.SetFileName("car.bmp");
ShowWindow(ghWnd_Main, nCmdShow); // Show using the specific show style
}
// for(int i=0; i<=200; i++)
// {
// TEST.Paint();
// TEST.x = i;
// }
//=================== Handle message loop ==================================================
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); // Translate keycode messages
DispatchMessage(&msg); // Send to the window
}
UnregisterClass("TESTCLASS", hInstance); // Unregister our window class
return msg.wParam; // msg.wParam contains the code passed to PostQuitMessage()
}
//=========================FUNCTIONS===============================
void SetFont(HWND hWnd, int iPointSize, const char *pcFontName) { //(obviously) sets fonts of controls
HFONT hTheFont;
HDC hDC = GetDC(hWnd);
int nHeight = -MulDiv(iPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
hTheFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, pcFontName);
ReleaseDC(hWnd, hDC);
SendMessage(hWnd, WM_SETFONT, (WPARAM)hTheFont, TRUE);
}
Abdul thats perfect! thanks so much for all your time! And everyone else too! :D :cool:
Hi Steve, is the code above to load a DIB?
It is strange to use a DDB bltbit function to blit a DIB.
For DIB, there are StretchDIBits() and SetDIBitsToDevice() APIs which are faster than DDB's equivalents.
Pls reply as I am looking for source code to load DIBs.
The CBitmap class in MFC is for DDB and doesn't include a function to load bitmap from files, except from resources.
That's why I have to use LoadImage() Win32 API and MFC CBitmap together.
I wonder why MS doesn't create a class to encapsulate DIB as well.:rolleyes:
He uses DIB sections, which are strange hybrids between DDBs and DIBs. StretchDIBits and SetDIBitsToDevice are slow, especially on WinNT.
In MFC7 there is the new CImage class which is capable of loading BMP, GIF, JPEG and PCX natively and can be extended by extending GDI+ images to other formats.