Archive

Posts Tagged ‘microsoft’

Windows Programming: Creating/Using DLL’s

September 8th, 2009 admin 2 comments

In the world of programming, there are MANY different types. Unfortunately, programming for some systems is different than others, but it’s things like that which keep the world turning. Today, we will discuss what exactly is a Dynamic Link Library (DLL) and how to use them to keep our programming easier and more organized. I will also include an Italian translation of this tutorial in the download source below! (Un traduzione del questo tutorial è in il download link per richiesta)

We’ll begin with what a DLL is and what it’s purpose is. A DLL is a wonderful tool to keep your programs organized by creating a DLL per set of functions. Also, it helps developers keep their closed source functions closed source, but also allows (with proper documentation/instructions on doing so) other users to use their work. Below we will give a few simple examples on how it all works!

To create the DLL we will be using Microsoft’s Visual C++. This is a free IDE compiler. I use it for any sort of Windows programming that I may do and will include the solution file in the download. Of course, I prefer GNU’s GCC which is also free, but the Windows ports of the compiler are not as good as the standard linux version.

The first note that I want to make is that if you’re making this project on your own (and not using my solution file), be sure to go to Project->Your Project’s Properties->Configuration Properties->General->Configuration Type and change it to “Dynamic Library (.dll)” otherwise it will not compile correctly.

Now in this tutorial, I am assuming you already know how to write programs, so this first file is test_dll.cpp. It contains the actual definitions, etc. of our functions:

/**
* Test Dynamic Library File
*
* (C) 2009 Dennis J. McWherter, Jr. All Rights Reserved.
*
*/

#define WIN32_LEAN_AND_MEAN // No need for the extra stuff.
// Non includere i file cui non hanno un scopo
#include <windows.h>
#include <iostream>
#include "test_dll.h" // Our header file
// Il nostro header file

using namespace std;

// Initiate the DLL (For programs)
// Iniziare il DLL (per i programmi)
BOOL APIENTRY DllMain(HINSTANCE dllHinst, DWORD reason, LPVOID lpvReserved){
// Use a switch to tell the program how to cycle the processes
// Usare un switch per fare il programma funziona
switch(reason){
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return true;
}

// The functions of our class. These are defined in "test_dll.h"
// Le funzioni del nostro class. Gli questi sono definire in "test_dll.h"

// Constructor
test_dll::test_dll(){}

// Basically a pointless function just to see how we can make them work together XD
// Una funziona senza la usa. è più di un demonstrazione.
char test_dll::func1(char lang){
return lang;
}

int test_dll::func2(float x,float y,char op){
// Simple math function!
// Semplice funziona della matematica
switch(op){
case 'a':
cout<< x << "+" << y << "=" << x+y;
return 0;
break;
case 's':
cout<< x << "-" << y << "=" << x-y;
return 0;
break;
case 'd':
cout<< x << "/" << y << "=" << x/y;
return 0;
break;
default:
cout<< x << "*" << y << "=" << x*y;
return 0;
break;
}
return 0;
}

Again, a fairly straightforward example. What you do have to notice in this that is different from most programs is that fact that we’re not really calling a “Main” function to be run. We call BOOL WINAPI DllMain instead. This next file is the header file. A rather important file overall as it let’s us know what to export.


/**
* Test Dynamic Library File
*
* (C) 2009 Dennis J. McWherter, Jr. All Rights Reserved.
*
*/

#ifndef HEADER
#define HEADER
// To keep the code clean we'll define this with a macro but this tells the processor
// to export whichever function/class it preceeds.
// Ci definiamo il questo con un macro ma ci vedremmo come lo funziona in più ritardo
#define EXPORT_DLL __declspec(dllexport)

// Now our class - If you export a class, all its functions come with! :) else do each function
// Adesso il nostro class! Se exporti un class poi i tutti funzione di lo sono exportare.
// se individuale ti exporti poi si deve __declspec(dllexport) per ogni
class EXPORT_DLL test_dll{ // = class __declspec(dllexport) test_dll{
public:
test_dll(); // Constructor/Costruttore
char func1(char lang); // First function definition/La definizione della prima funziona
int func2(float x,float y,char op);
};

#endif

The comments explain it, but it’s really worth going over again. EXPORT_DLL is defined just for the purpose that we could potentially have more than a single class to export. This goes both ways for the dllexport and dllimport options, so really, EXPORT_DLL just translates to __declspec(dllexport) which would also work if you replaced EXPORT_DLL. Now, compile that code and VC++ should provide you with a .dll file and a .lib file with whatever name you gave the project (in our case: “DLL_Tutorial.lib/.dll”).

Now, you cannot run DLL files by themselves; you need a client program (.exe) which is what we’re getting to now. For the sake of brevity, we will just make this a simple console program which runs the proper functions. Now, create a new project and make sure you copy the “DLL_Tutorial.lib” file into the source directory. You need the .lib file to compile the client program, but you only need the .dll to run the program.

So here is the client main file. A console program of course to keep things simple :) We’ll call this test_client.cpp

/**
* Test Dynamic Library File
*
* (C) 2009 Dennis J. McWherter, Jr. All Rights Reserved.
*
*/

#include <iostream>
#include <string>
#include "test_client.h"

using namespace std;

int main(){
// Create object to class
// Creare l'oggetto a class
test_dll test;

// Init var
string num1,num2,addition,subtraction,division,multiplication,ans,operation;
float x,y;
char choice[5], op[5]; // Allow more chars just in case - otherwise we'll break the script :(
// Permettere dei più caratteri così non ci romperiamo il script! :(
cout<< "Please select a language\r\n\r\nEnglish - en\r\nItaliano - it\r\n \r\nSelect: ";
cin>>choice;
switch(test.func1(choice[0])){
case 'i':
num1 = "Numero 1: ";
num2 = "Numero 2: ";
addition = "Per piacere selezi i tuoi numeri per aggiungiere";
subtraction = "Per piacere selezi i tuoi numeri per sottrarre";
division = "Per piacere selezi i tuoi numeri per dividere";
multiplication = "Per piacere selezi i tuoi numeri per moltiplicare";
ans = "La tua risposta: ";
operation = "\r\nPer piacere selezi il tuo operazione:\r\na - Aggiungiere\r\ns - Sottrarre\r\nd - Divisione\r\nm - Moltiplicazione\r\n\r\nSelection: ";
break;
default:
num1 = "Number 1: ";
num2 = "Number 2: ";
addition = "Please select your numbers to add";
subtraction = "Please select your numbers to subtract";
division = "Please select your numbers to divide";
multiplication = "Please select your numbers to multiply";
ans = "Your answer: ";
operation = "\r\nPlease select your option:\r\na - Addition\r\ns - subtraction\r\nd - Division\r\nm - Multiplication\r\n\r\nSelection: ";
break;
}

cout<< operation;
cin>>op;
cout<< endl << endl << num1;
cin>>x;
cout<< endl << num2;
cin>>y;

test.func2(x,y,op[0]);

cout<< endl << endl << "Type in anything to exit...";
cin>>op;

return 0;
}

Naturally, the header file that follows is test_client.h

/**
* Test Dynamic Library File
*
* (C) 2009 Dennis J. McWherter, Jr. All Rights Reserved.
*
*/

#ifndef TEST_HEADER
#define TEST_HEADER
#define DLL_IMPORT __declspec(dllimport) // Same concept as export
// Il stesso concepto come export

// Define the class

// What is the purpose of redefining? That's all you need to do is redefine structure ;)
// and not function :)
// Perchè ti deve ridefinire la class? Perché solo lo struttura si deve essere definire!
// e no funziona :)
class DLL_IMPORT test_dll{
public:
test_dll(); // Constructor/Costruttore
char func1(char lang); // First function definition/La definizione della prima funziona
int func2(float x,float y,char op);
};

#endif

Within these two files, they are essentially creating a calculator. Since I wrote this program in dual languages, I added SIMPLE (meaning hard-coded) dual language support into the program. Also, this gives a reason for the first function, just to see how one can use multiple functions from a DLL just as if they were in the source.

If anyone has further questions or is receiving errors, feel free to let me know and I will be glad to help! Now make sure, however, that everything is set right as well. I ran into an error compiling the client the first time because my project subsystem (found in project properties->linker->System) was set to WINDOWS rather than CONSOLE so it was looking for the WINMAIN where there was none. So just a word of caution to anyone trying this without my source and you are receiving a WINMAIN compilation error.

So the land of DLL’s really aren’t as complex as it seems. It’s simply a closed source utility which helps other developers in WINDOWS programs.

Regards,
Dennis M.

DLL Tutorial Source Code and Binaries

C++ Programming: Visual Windows

April 24th, 2009 admin No comments

I am primarily a programmer for *nix platforms and some cross compatibility for the DOS command prompt as many of you know. However, I also program Windows in the visual sense (how most end-users envision their product). So I’m going to write up a quick tutorial for you guys today!

I am compiling the example with Microsoft’s Visual C++. I am not normally an advocate for most things made by Microsoft, but in this case there is no doubt that this is the best compiler for compiling Windows programs. The best part about it is (unexpected, I know; it is Microsoft after all) that the compiler is FREE and comes with a very nice and clean GUI.

Now be mindful, the example has small functionality, but it is more or less the basis to ALL Windows programs! As we go through, we’ll explain the importance of each part. So let’s begin with the main file so you can see what’s going on.

main.cpp

/**
* Windows Programming Tutorial by Dennis M.
*
* main.cpp
*
*/

// Basic includes :D
#include <windows.h> // Win32 Lib
#include “menu.h” // Our menu – we’ll explain this later ;)
// more commonly named “resource.h,” but for
// explanation purposes this is easier :)

// Main WindowProcedure Definition
LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
const char szClassName[] = “MicrosonicTestProgram”; // Our program’s name

int WINAPI
// Our main class to make the Window
WinMain(HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArg,int WindowStyle)
{
// Pointer definitons
HWND hwnd;
MSG msgs;
WNDCLASSEX wcl;

// Standard window properties
wcl.hInstance = hThisInstance;
wcl.lpszClassName = szClassName;
wcl.lpfnWndProc = WindowProcedure;
wcl.style = CS_DBLCLKS;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wcl.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = “MAIN_MENU”;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

if(!RegisterClassEx(&wcl)){
return 0;
}

hwnd = CreateWindowEx(
0,
szClassName,
“Microsonic.org Test Program”,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
640,
480,
HWND_DESKTOP,
LoadMenu(hThisInstance,”MAIN_MENU”),
hThisInstance,
NULL
);

// This is where we see the window.. ShowWindow()… duh!
ShowWindow(hwnd,WindowStyle);
while(GetMessage(&msgs,NULL,0,0)){
TranslateMessage(&msgs);
DispatchMessage(&msgs);
}
return msgs.wParam;
}

// Here we process all the commands etc.
LRESULT CALLBACK WindowProcedure(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
switch(msg){
// Process commands sent to the program
// In this case, from the menu items
case WM_COMMAND:
switch(wParam){
case MM_FILE_NEW:
MessageBox(hwnd,”MDI is more complex! Another tutorial soon perhaps on it! This is just the basics to Windows programming!\r\nSorry!”,
“Feature Not Available”,MB_OK);
return 0;
break;
case MM_FILE_EXIT:
PostQuitMessage(0);
return 0;
break;
case MM_HELP_ABOUT:
MessageBox(hwnd,”\tMicrosonic.org test program!\r\n\r\n\tFor more tutorials visit:\r\n\r\n\thttp://microsonic.org! \r\n”,
“Microsonic.org Test Program”,MB_OK);
return 0;
break;
case MM_HELP_VISIT:
ShellExecute(hwnd,”open”,”http://microsonic.org”,NULL,NULL,0);
return 0;
break;
}
break;
// If they hit the “X” button
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
// Default loop
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
break;
}
return 0;
}

Some basic points I’d like to touch upon. Since this is just the basics to the Window, I have not included MDI (allowing text, etc. through the new button) but, this is important for the generalization of the program. If you understand how this works, Windows programming becomes very similar to all other sorts of programming with the assistance of the MSDN Library. Now, realize that the structure file for the menu is never directly included into any C++ file, but rather automatically linked. Make sure you keep it this way and don’t make the mistake of including a .rc file. Also, as I peer through the code, it is important to realize that many of the function names are static. For the basics, all Windows programs should look as some sort of variation to this code simply by definition of a Windows program.

Now, let’s continue to see the header file. This purely holds definitions for the resource file holding the menu structure. If they are not defined, they will not work properly.

menu.h

/**
* Windows Programming Tutorial by Dennis M.
*
* menu.h
*
* Contains all our menu definitions
*
*/

// Give values to menu items
#define MM_FILE_NEW 2001
#define MM_FILE_EXIT 2002
#define MM_HELP_ABOUT 3001
#define MM_HELP_VISIT 3002

As you can see, each menu item is defined. These numbers are more or less arbitrary, you just want to make sure their definitions don’t conflict with each other or any other aspect of your program. I personally like to keep menu items grouped together, so I defined the “File” items in the 2000‘s and the “Help” items in the 3000‘s.

Finally, the structure of our menu. A resource file that is never really included.

menu.rc

/**
* Windows Programming Tutorial by Dennis M.
*
* menu.rc
*
* Resource file which contains the menu structure!
* To edit the file with Free Visual C++
* Right click and “View Code”
* Again, more commonly named “resource.rc”
*
*/
// Menu definitions
#include “menu.h”

// Should be able to get the hang of the menu ;)
MAIN_MENU MENU
BEGIN
POPUP “&File”,
BEGIN
// Format: MENUITEM “Title”, COMMAND_TO_SEND
MENUITEM “N&ew”, MM_FILE_NEW
MENUITEM SEPARATOR
MENUITEM “E&xit”, MM_FILE_EXIT
END
POPUP “&Help”
BEGIN
MENUITEM “A&bout”, MM_HELP_ABOUT
MENUITEM SEPARATOR
MENUITEM “G&oto Microsonic.org”, MM_HELP_VISIT
END
END

The structure is fairly straight forward, so I can probably leave it without much explanation. The only thing I would like to say is that you should realize how usable menu items are presented.
MENUITEM “Display Text”, DEFINED_FUNCTION.
The defined function is what is sent to the main loop of the program and is processed in the “switch.” Just remember this when you’re creating your programs!

As usual, I will provide complete source WITH the VC++9 Project file!

If you choose to make your own project, please make sure you go to the “General” tab and create an empty project. Compiler options in other Visual C++ presets do not work properly for many reasons. A major error one could run into (if using another setting) is compiling UNICODE which would break “const char szClassName[]” by definiton. You would then have to declare it as _T string.

Simple Win32 API Tutorial

Regards,
Dennis M.