How To Draw A Bitmap in A MFC Dialog Window
How To Draw A Bitmap in A MFC Dialog Window
How To Draw A Bitmap in A MFC Dialog Window
window
Loading a bitmap into our dialog window is not a difficult task. This article describes how
to do that and provide you with an example project.
Create a dialog based MFC application. We have to add the bitmap we are going to
display as a resource to our application. Open resource view of the left pane, right click on
the project and select Add->Resource.
Select Bitmap as the resource type and click "Import". Then browse and select the bitmap
file you want to add. Then it will be added to the project as a bitmap resource. You can
see and edit it using visual studio.
We are going to load our bitmap to the main dialog of our application when we click a
button in the dialog. So, first delete all the controls in the dialog and add a button to the
dialog. Add the following code to the handler of that button.
void CdrawbitmapDlg::OnBnClickedButton1()
{
CRect r;CBitmap* m_bitmap;CDC dc, *pDC;BITMAP bmp;
pDC = this->GetDC();dc.CreateCompatibleDC(pDC);dc.SelectObject(m_bitmap);
pDC->BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &dc, 0, 0, SRCCOPY);
m_bitmap->DeleteObject();m_bitmap->Detach();}
Ok. Lets try to understand the code. We have to obtain what is called the device context of
our window and draw in it. Then what we draw is displayed in the window. Similarly, if
we need to print a document, what we have to do is obtain the device context of the
printer and draw in that device context. That will print what we have drawn in the device
context. We obtain the device context of the window by calling GetDC() function.
We use CBitmap to load and store the bitmap. LoadBitmap() function of CBitmap loads
the bitmap specified by the parameter which is the resource identifier of the bitmap we
have added as a resource. I have not changed the default resource identifier given by
Visual Studio so still it is IDB_BITMAP1. If you have given a different name to the
bitmap resource you added, you have to use that name as the argument to LoadBitmap().
Then, we use BitBlt() function to draw the bitmap in the device context. It has several
parameters.
The first two parameters specify the upper left coordinates of the destination rectangle.
You can change them and experiment to understand the use of them.
Next two parameters specify the width and height of the destination rectangle. We have
given the actual width and height of the bitmap we are going to load as these parameters.
We can't directly get the width and the height of the bitmap with CBitmap. So we have
used BITMAP data type for that purpose.
The fifth argument is the device context from where we copy the bitmap.
The next two arguments are the upper left corner of the source bitmap. We have given 0
as both arguments so the actual upper left corner of the image is selected. You can give
different positive values for this arguments (say 100, 100) and experiment to understand
how it works.
Now you should be able to compile and run the application. You can download example
project source code from here.
• Both the library and the application should be built for same runtime
environment.
• Both the library and the application should be built in same configuration, either
debug or release.(if lib is built in debug, the app also should be built in debug. if
lib is built in release, the app should also be built in release)
So, follow the instructions carefully when you are creating the lib and the application.
1. Open Visual Studio and select File->New->Project. From the dialog you get,
select Visual C++->Win32->Win32 Project. Give name "libtest" to the project
and select a location for save your project. Click OK.
2. Click Next. Choose Static Library for Application type and click Finish.
3. Replace the stdafx.h header file in the project folder with this one. This header
contains the additional headers you need.
4. Select project name in the solution explorer pane, which is in the left of the
window and go to project->properties in the main menu.
5. In configuration properties->C/C++->Code generation, change Runtime Library
to Multi-Threaded (/MT)
6. Select Project->Add Class from main menu. Select C++ and select Add. In the
dialog you get, enter "testclass" for class name and click Finish.
7. Go to Class View in the left pane and find the class you added. Right click on it
and select Add->Add Function. Enter "void" for return type and "Greeting" for
function name and click Finish.
8. Add the following code to the function "Greeting".
void testclass::Greeting(void)
{
::MessageBox(0, TEXT("have a nice day!"), TEXT("hello...."), 0);}
9. Build the project. You can find the library file you built ("libtest.lib") in the
"Debug" folder in project directory.
1. Create a dialog based MFC application which uses MFC in static library. Leave
the other settings in their default values. You can read article getting started with
MFC for more information. Use name "tester app" to the project.
2. By using step 4 and 5 of creating lib, Change the runtime library to Multi-
Threaded. As mentioned at the beginning, both the library and the application
which uses the library should use same runtime library.
3. Copy the library file "libtest.lib" which we built to the folder where the source
files of tester application are in.
4. Open project properties. In configuration properties->Linker->Input->Additional
Dependencies, type libtest.lib.
5. Delete 2 buttons and the static text in the main dialog of your MFC application
and add a button to the dialog.
6. Double click the button you added to go to the handler function for that button.
Add following code to the function.
void CtesterappDlg::OnBnClickedButton1()
{
testclass a;
a.Greeting(); }
7. Copy "testclass.h" which is in the folder where the source files of our library are
kept to the source file folder of tester application. Then include that header file in
the page where above code is written. The header file should be included after the
include statements which are already there. The class definition of the class
"testclass" we added to the library is in that header file. This step is done because
we are using the class "testclass" in above code. In this header file, only the
definition of the class is available. The implementation of the class is in the lib
file "libtest.lib".
8. Build and run the application. If you press the button you added to the main
dialog of the application, you will get the greeting, which we wrote when we are
creating the library.
If you want to build the tester application in release mode, you have to compile the
library in the release mode and use that library file instead of the previous "libtest.lib".
Also, remember you have to change the runtime library to Multi-Threaded again for
release mode for both library and tester applications. That is because the settings for
release and debug modes are kept separately (i.e. if you change the runtime library for
debug mode, that do not change the runtime library for release mode).
Because CDatabase and CRecordset uses ODBC interface to connect to work with a
database, we first have to create an ODBC data source. Here are the steps for Windows
XP.
Lets now create our simple application which connects to our newly created data source.
It is better if you use some meaningful names to the control ids of the edit boxes. I have
used IDC_USERNAME, IDC_FIRSTNAME, IDC_LASTNAME, IDC_EMAIL,
IDC_COUNTRY. You can change the control id of edit box from the properties of the
edit box.
Now, go to view class of your application and locate DoDataExchange() function. In this
sample application, it is located in the file "db accessView.cpp".
In this function, you can "bind" the fields of our form to the fields in the table of our
database. A CRecordset variable (m_pSet) is created for us by the application wizard.
This variable corresponds to the table in our database and it has a mamber variable for
each field in the table. Here is the DoDataExchange function.
All the fields in our databse table are strings. So we have use DDX_FieldText function
for bind the variable to the text boxes in our form. There are other functions such as
DDX_FieldCBIndex to synchronize with other data types.
You will have to include "resource.h" header to the cpp file with above code to compile
the project. Now, if you compile the application, you will get an error. If you go to the
location of error, you will see #error preprocessor directive telling that the passwords
may be in the connection string . just comment that line. Now you should be able to
compile the project.
Now, we have created a simple application so easily which can read and edit the data in a
database table. You will get a toolbar to go through the records in the table.
Now, lets see how to we can add a new record to the database table. You can see a button
on our form to add a new record to the database table. here is the handler of that button.
void CdbaccessView::OnBnClickedButton1()
{
adduserdlg dlg;
if(dlg.DoModal()==IDOK)
{
UpdateData(FALSE);
m_pSet->AddNew();
m_pSet->m_username=dlg.username;
m_pSet->m_firstname=dlg.firstname;
m_pSet->m_lastname=dlg.lastname;
m_pSet->m_email=dlg.email;
m_pSet->m_country=dlg.country;
m_pSet->Update();
m_pSet->Requery();
UpdateData(FALSE);} }
I have created a dialog to display when that button is clicked. If you do not know how to
create a dialog, see creating custom dialogs in MFC section. The class of this dialog is
"adduserdlg". I have created a variable form that class and have called DoModal function
to display the dialog. If user fills the data and clicks OK in that dialog, we add the new
record to the database table. To add a new record to the database table, we first call the
AddNew() function of the CRecordset variable corresponds to that table. Then we assign
values to the each field in the table. After that, we call Update() and Requery() fucntions
to save the data to the database.
You can download the source code of the sample application here.
Download the Access database file here.
For the example application to work properly, you have to copy database.mdb to C: drive
and create an ODBC data source with name 'test' from that file.