Solved

BMP not appearing

Posted on 1998-05-15
6
331 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 100 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
This article surveys and compares options for encoding and decoding base64 data.  It includes source code in C++ as well as examples of how to use standard Windows API functions for these tasks. We'll look at the algorithms — how encoding and decodi…
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…
A company’s greatest vulnerability is their email. CEO fraud, ransomware and spear phishing attacks are the no1 threat to a company’s security. Cybercrime is responsible for the largest loss of money to companies today with losses projected to r…

932 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now