?
Solved

BMP not appearing

Posted on 1998-05-15
6
Medium Priority
?
339 Views
Last Modified: 2013-12-03
Below is the part of the source code for my program. I've created a standard file open dialog. After obtaining the path name for the file, I use LoadBitmap() function to display the bmp..but nothing happens..Did i do something wrong?

This portion is from the CNNDlg.cpp file for fileopendialog

void CNNDlg::OnFileOpenfile()
{

      char sBMPFile[500];
        //string containing path and file name
      char FileTitle[100];
        //string containing only file name without path

            OPENFILENAME ofn;            
                ofn.lStructSize = sizeof(OPENFILENAME);
            ofn.hwndOwner=m_hWnd;
            ofn.hInstance=NULL;

            ofn.lpstrFilter =
                TEXT("Bitmap picture files *.bmp\0*.bmp\0ALL Files *.*\0*.*\0\0");

            ofn.lpstrCustomFilter=NULL;
            ofn.nMaxCustFilter=0;
            ofn.nFilterIndex=1;
            ofn.lpstrFile=sBMPFile;
            ofn.nMaxFile=500;
            ofn.lpstrFileTitle=FileTitle;
            ofn.nMaxFileTitle= 99;
            ofn.lpstrInitialDir = NULL;
            ofn.lpstrTitle = "Open Fingerprint File";
            ofn.Flags = OFN_FILEMUSTEXIST;
            ofn.lpstrDefExt = "BMP";
            ofn.lCustData=NULL;
            ofn.lpfnHook=NULL;
            ofn.lpTemplateName=NULL;

            sBMPFile[0]='\0';

            GetOpenFileName(&ofn);

            if (sBMPFile[0] == '\0')
            {
                  return;
            }

            hbitmap =
                    ::LoadBitmap(m_hInstance, sBMPFile);

            Invalidate();
      
}


This portion is from the OnPaint() in the CNNDlg.cpp file
      
void CNNDlg::OnPaint()
{
      if (IsIconic())
      {
      CPaintDC dc(this); // device context for painting

      SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

            // Center icon in client rectangle
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;

            // Draw the icon
            dc.DrawIcon(x, y, m_hIcon);
      }
      else
      {
      
      if (hbitmap!=NULL)
      {
            CPaintDC dc(this);

            // Create a memory DC
            HDC hMemDC = ::CreateCompatibleDC(NULL);

            //Select the bitmap in the memory dc
            SelectObject(hMemDC,hbitmap);

            //Copy the memory dc into the screen dc
            ::StretchBlt(dc.m_hDC, //destination
                               50,
                               50,
                               200,
                               200,
                               hMemDC, //Source
                               0,
                               0,
                               510,
                               480,
                               SRCCOPY);
            // Delete the memory DC and the Bitmap
            :: DeleteDC(hMemDC);
            :: DeleteObject (hbitmap);
      }

      CDialog::OnPaint();
      }

}
0
Comment
Question by:stefi
  • 3
  • 2
6 Comments
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1402034
There are several potential problems I see.

1. Only create one CPaintDC for the entire duration of the OnPaint method. The destructor of CPaintDC calls EndPaint which validates the area and hence you can't draw on the area again.

2. Don't send the WM_ERASEBKGND message because that's already been done for you. And especially don't send somebody else your DC because they may do something to it that you don't expect.


0
 

Author Comment

by:stefi
ID: 1402035
Sorry, I think you have to help me out abit more. I'm having difficulty in understanding what you wrote.

What I noticed is that, the functions yu mentioned where actually written for me by the Appwizard from VC++ 4.0. So do i just delete off the part before
if (hbitmap!=NULL) ?

If not, could yu modify my code so that it works?

Cheers

0
 
LVL 3

Accepted Solution

by:
Norbert earned 400 total points
ID: 1402036
1. As I know LoadBitmap is for loading from a resource not from a file
2. Bmp files stored on disks are normaly device independent bitmaps that first must be converted to device depend bitmaps
so you should have a look on DIB inside the online help.
There is also an example DIBLOOK that can show you what you have to do if you want to load a Bitmap from the disk

To show you  here what you have to do ist to much but I think the sample DIBLOOK will show the most.


0
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 

Author Comment

by:stefi
ID: 1402037
Thank you for your answer. I now understand that I cannot use the LoadBitmap function to load a bmp from file.
I've looked at the DIBLOOK program and the source code. If it is possible, could yu help me out here. I've printed all the source code out and am trying to figure out with portion of the code refers to what and how I may be able to use it.
In 'myfile.cpp' there is a portion that loads a DIB from a file. How do I extract that and use it in my program. Basically, what I'm not sure is how I can include this in my program. DO i just type include<myfile.cpp> ? or the h file or what. Please. I'm very new at this.
0
 
LVL 3

Expert Comment

by:Norbert
ID: 1402038
Something fundamental:
A program written in C or C++ normaly contains more than one source file (.C or .CPP) . Within these files there is the source code of the program. The .H files contains normaly only declarations.
If you want to add a complete source file you do not include the cpp File. If you are using Visual C++ you insert the file into your project.
I have VC++ 4.2 there is a menu entry Insert and within the insert menu there is a entry Files into Project ... there you select the file to add. If you want to have access to functions within the added file from other files the compiler has to know that the functions exists therefore are the header files I make an example:
File1.cpp:
#include "File1.h"
#include "File2.h"

void MyFuncThatCallsFuncOfOtherProgram()
{
       printf("The other func returned %d\",CallOtherFuncThatAdds2Int(1,2));
}
if the compiler compiles these file he has to know something about CallOtherFuncThatAdds2Int
therefore the header files:
//File1.h
void MyFuncThatCallsFuncOfOtherProgram();//declaration of function from file1
//File2.h
int CallOtherFuncThatAdds2Int(int first,int second);

now the compiler knows if he compiles the File1 that there is anywhere a function CallOtherFuncThatAdds2Int that gets 2 integers and returns 1 integer
//File2.cpp
int CallOtherFuncThatAdds2Int(int first,int second)
{
  return first+second;
}
after both files are compiled the linker concatenate the both files to an executebal and seraches for references between the 2 files
the linker now knows where the adresses of the functions are and can concatenate the relations.

if you don't want to add a complete file simple copy the parts you need from one to an other
for example the Ondraw from diblook to the ondraw of your progam

Note: The Diblook program was originally written for Windows 3.x
Thats the reason for the GlobalAlloc GlobalLock and GlobalFree calls.
Because if you use win 95 or win NT there is no real global memory you can replace the mysterious Global... functions and the casting by new and delete.
for example:
HGLOBAL handle =GlobalAlloc(SomeFlags,sizeof(BitmapHeaderInfo);
char* ptr=(LPSTR)GlobalLock(handle);
CallSomeFunc((BitmatHeaderInfo*)ptr)
GlobalUnlock(handle)
GlobalFree(handle);
replace with
BitmapHeaderInfo* ptr=new BitmapHeaderInfo
CallSomeFunc(ptr)
delete ptr

0
 

Author Comment

by:stefi
ID: 1402039
Thank you for your instruction. I think I can figure it out now..
Hopefully I'm successful. Thanks again

Stefi
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Loops Section Overview

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question