This problem has been bugging me for two days now.
I am trying to make a DLL, it exports many classes containing properties, variables, functions and a constructor.
I am using VC++ 2005 on Windows Vista Basic.
My project is the WGCL C++ control library. It is a mask for the WinAPI common controls. And since the files are so big, they all must be in their own header.
My goal is for the dll to be loaded with LoadLibrary only, no linker options, nothing else at all.
Which I know is possible because Scintilla does this.
Here is what I have:
WGCL2.cpp
#define WGCL_VERSION 0x0200
#include <windows.h>
#include <commctrl.h>
#define DLLEXPORT __declspec(dllexport)
#include "TextBox.h"
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
TextBox.h
#define WGCL_TEXTBOX
class DLLEXPORT TextBox
{
private:
// Underlying Property Variables
LPSTR _Text;
HWND _hwnd, _Parent;
bool _MultiLine; // ReadOnly, after Set
bool _Visible;
bool _Enabled;
bool _ReadOnly;
int _x, _y;
int _width, _height;
int _ControlID; // ReadOnly, after Set
public:
// Underlying Property Get() & Set(val) Operations
LPSTR Text_Get()
{
LPSTR buffer;
buffer = (LPSTR)GlobalAlloc(GPTR, (GetWindowTextLength(hwnd) + 1));
GetWindowText(hwnd, buffer, (GetWindowTextLength(hwnd) + 1));
return buffer;
}
void Text_Set(LPSTR val) { _Text = val; SetWindowText(hwnd, Text); }
HWND hwnd_Get() { return _hwnd; }
void hwnd_Set(HWND val) { _hwnd = val; }
HWND Parent_Get() { return _Parent; }
void Parent_Set(HWND val) { _Parent = val; }
bool MultiLine_Get() { return _MultiLine; }
bool Visible_Get() { return _Visible; }
void Visible_Set(bool val)
{
_Visible = val;
if (val == true)
ShowWindow(_hwnd, SW_SHOW);
else
ShowWindow(_hwnd, SW_HIDE);
}
bool CanUndo_Get() { return FromBOOL(Send(EM_CANUNDO, 0, 0)); }
bool ReadOnly_Get() { return _ReadOnly; }
void ReadOnly_Set(bool val) { if(Send(EM_SETREADONLY, val, 0)) _ReadOnly = val; }
bool Enabled_Get() { return _Enabled; }
void Enabled_Set(bool val) { if(EnableWindow(_hwnd, val)) _Enabled = val; }
int X_Get() { return _x; }
void X_Set(int val) { _x = val; Resize(_x, _y, _width, _height); }
int Y_Get() { return _y; }
void Y_Set(int val) { _y = val; Resize(_x, _y, _width, _height); }
int Width_Get() { return _width; }
void Width_Set(int val) { if(Resize(_x, _y, _width, _height)) _width = val; }
int Height_Get() { return _height; }
void Height_Set(int val) { if(Resize(_x, _y, _width, _height)) _height = val; }
int ControlID_Get() { return _ControlID; }
int TextLength_Get() { return GetWindowTextLength(_hwnd); }
// Constuctor
TextBox::TextBox(LPSTR, HWND, bool, int, int, int, int, int);
// Properties
_declspec( property( get=Text_Get, put=Text_Set ) ) LPSTR Text;
_declspec( property( get=hwnd_Get ) ) HWND hwnd;
_declspec( property( get=Parent_Get, put=Parent_Set ) ) HWND Parent;
_declspec( property( get=MultiLine_Get ) ) bool MultiLine;
_declspec( property( get=Visible_Get, put=Visible_Set ) ) bool Visible;
_declspec( property( get=CanUndo_Get ) ) bool CanUndo;
_declspec( property( get=ReadOnly_Get, put=ReadOnly_Set ) ) bool ReadOnly;
_declspec( property( get=Enabled_Get, put=Enabled_Set ) ) bool Enabled;
_declspec( property( get=ControlID_Get ) ) int ControlID;
_declspec( property( get=X_Get, put=X_Set ) ) int x;
_declspec( property( get=Y_Get, put=Y_Set ) ) int y;
_declspec( property( get=Width_Get, put=Width_Set ) ) int width;
_declspec( property( get=Height_Get, put=Height_Set ) ) int height;
_declspec( property( get=TextLength_Get ) ) int TextLength;
// Functions
bool Create();
bool Update();
bool Destroy();
bool FitToWindow();
bool Resize(int, int, int, int);
bool SetPos(HWND, int, int, int, int, UINT);
void Undo();
void Cut();
void Copy();
void Paste();
void Delete();
void Clear();
LRESULT Send(UINT, WPARAM, LPARAM);
};
TextBox::TextBox(LPSTR text_, HWND parent_, bool multiline_, int x_, int y_, int width_, int height_, int controlid_)
{
_Text = text_;
_Parent = parent_;
_x = x_;
_y = y_;
_width = width_;
_height = height_;
_ControlID = controlid_;
_Enabled = true;
_ReadOnly = false;
}
That is a little over half of the code of TextBox.h, now you see why they must be in different files.
When I use LoadLibrary to load the dll, the compiler says the symbols are loaded. But when I try to create an object with the TextBox class, it says "error C2065: 'TextBox' : undeclared identifier".
I know it is because the class is not exporting correctly. But what I don't know is how to import and export them correctly. I have searched all kinds of websites, from MSDN to CodeProject. And to no success.
How could I export the various functions, variables, constructors and enums from my DLL and import them into my application.
Thanks in advance. :)