although i didnt understand the role of __declspec(dllexport) and __declspec(dllimport) |
Do you understand them now, though? Just in case you still don't, let me explain.
When you have
__declspec(dllexport)
in front of a class or function, this says to the compiler that you want to
expose this class or function to the user of this DLL.
Now, let's say you want to create a DLL with two functions, one called "intAdd" which adds two integers and one called "intMultiply" that multiplies two integers. The header file for your DLL will look like this:
1 2
|
__declspec(dllexport) int intAdd(int x, int y);
__declspec(dllexport) int intMultiply(int x, int y)
|
Let's say you have a customer and you have provided them your DLL as well as the above header file (and a .lib)...They wouldn't be able to use your DLL!
This is because
__declspec(dllexport)
tells the compiler that you want to expose these functions. But that's not what the customer wanted! They wanted to
use the functions from the DLL. Now Your customer is angry because they're getting linker errors about how intAdd and intMultiply aren't defined anywhere.
To fix this, you send the customer a new header file that looks like this:
1 2
|
__declspec(dllimport) int intAdd(int x, int y);
__declspec(dllimport) int intMultiply(int x, int y)
|
Now their project compiles fine and they're able to use your DLL. What
__declspec(dllimport)
does is it tells the compiler that the function is defined in the DLL and not in the current project. Your customer is happy and you get paid.
However, you have a slight problem. You now have
two header files instead of one for your DLL (one for you, one for your customer). This can be a big deal when your DLL has more than two exposed functions (or classes). To get around this we use the preprocessor
#ifdef
trick I showed you above. Let's say you add
MY_DLL_EXPORTS
to the preprocessor input in your project (it's safe to say your customer won't have the same thing defined).
You now change your header file to this:
1 2 3 4 5 6 7 8
|
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif
MY_DLL_API int intAdd(int x, int y);
MY_DLL_API int intMultiply(int x, int y);
|
When you compile your DLL with the above change, the preprocessor will place
__declspec(dllexport)
in front of the functions and when your customer compiles the DLL, the preprocessor will place
__declspec(dllimport)
in front of the functions. Now, you can create a DLL for your customer, and they will be able to use the DLL (without linker errors) all with only one header file! Mission accomplished.
what should the window style be in order to get a main frame window and then create a child window |
Well, it's been a while since I've used Win32 for window creation, but I would suspect that your main frame window can have any style, as long as it looks like how you want it. You might want to give the main frame window a
WS_CLIPCHILDREN style attribute so it doesn't waste time drawing things behind any child windows. The child window, however, should have
WS_CHILD (or
WS_CHILDWINDOW) as part of its style attribute set.
Note that you need to pipe style attributes together (using the
|
character).
e.g. say you want a window to be a child window with a title bar (caption), a system menu (this is the minimize/maximize and close buttons), a horizontal scroll bar, and you want it to receive focus if you press TAB. The style will look like this (the style attributes can be in any order):
WS_CHILD | WS_CAPTION | WS_SYSMENU | WS_HSCROLL | WS_TABSTOP