How to Add a Windows Form to a C++ Win32 DLL

Hi

I have a C++ Win32 DLL within which I have a function that has a looping calculation which can take some time. This function is then exported and then used within VBA Excel. I would like to add a Windows Form to the DLL which contains a progress bar so that as the code loops the progress bar increments thereby letting the user know how long is left.

However, I've been trawling the net and can't seem to find a solution. Admittedly, I'm fairly new to C++ so perhaps I'm missing something obvious
The basic form of the function would be
 
void samplecode()
{
// Add code here to intialise form with progress bar
 
// Set progressbar max to a value
 
// Set current progressbas value to 0
 
// Do looping calc
	for (int i = 0; i <= 255;i++)
                     {
                      // Add code here to increment progress bar
 
                     // Do some calculation
                      }
// Close Form 
// Exit Function
}

Open in new window

JACD1Asked:
Who is Participating?
 
DanRollinsCommented:
The solution is as simple as adding a dialog resource to the DLL and creating one control in the dialog box and then sneding messages to it to update itself -- then close the dialog box when finished with the calculation.
Do you have MFC support in your DLL?  (having it makes the dialogbox creation and manipulation very easy).
 
0
 
kaylanreilorCommented:
I think that currently your DLL is only existing to provide some calculation to another application. Then it is not a good idea at all to provide a GUI into this DLL. You should instead raise the even and catch it from the client application which will provide the GUI. So here your client application is Excel.
Nevertheless, if you absolutely want to do it into the DLL, you should better forget Winforms here and learn how to do it with MFC or ATL/WTL. You will find a lot of complete example on the web, for example here are some articles on codeproject:
http://www.codeproject.com/KB/miscctrl/cskinprogress.aspx
http://www.codeproject.com/KB/miscctrl/progressctrlx.aspx
http://www.codeproject.com/KB/miscctrl/text_progressctrl.aspx

Now, if you really, really do want to add a winform to your win32 DLL, first of all you will have to add a specific cpp file in your project only to have into THIS file the support of the CLR. Into this file you will write some C++/CLI code. You can do that by right-click on this source file in solution explorer and open the property page and then in C/C++=>General=>Compile with Common Language Runtime support set the value "Common Language Runtime Support (/clr)". Thus you will be able to code your winform the same way that VS generally generate them as the following. After, you wuill add references on System and System.Windows.Forms. All this is the most complicated to add a WinForm but on the other hand it is the more secure. You are going to mix in the same project unmanaged and managed C++. If you do a mistake like defining a global variable of an unmanaged class that needs a constructor (like an STL container for example) in the managed code part you will have some unpredictible crash at run time.

BUT, you can do it more easily. Currently if you right-click on your project in solution view and then click Add=>New Item and then choose a winforms form, Visual Studio will warn that it has to convert the project sio that the support on the CLR will be added on the whole project and your WinForm will be generated. In that case you will have to deal with the directives "#pragma managed" and "#pragma unmanaged" to clearly tell to the compiler which part is managed and which part is not. But you will have to discover it later on, simply by using your new mixed DLL !
public ref class MyWinForm : public System::Windows::Forms::Form
{
public:
	MyWinForm(void)
	{
		InitializeComponent();
	}
 
protected:
	~MyWinForm()
	{
		if (components)
		{
			delete components;
		}
	}
 
private:
	System::ComponentModel::Container ^components;
 
	void InitializeComponent(void)
	{
		this->components = gcnew System::ComponentModel::Container();
		this->Size = System::Drawing::Size(300,300);
		this->Text = L"MyWinForm";
		this->Padding = System::Windows::Forms::Padding(0);
		this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    }
};

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.