Create window form C++ function using MFC or Win32 API
Hello,
My setup is as follows:
There is function written C++, that must be compiled to DLL. This DLL is linked to some CAD (computer aded design) tool, that has special interface for it.
I want to add to this function some GUI (graphical user interface). So the creation of a window is necessary.
I've tried already with Win32, but without success.
The problem is that CreateWindow function requires application instance handle, that is provided by Windows itself when window is created in "normal conditions".
Any ideas ?
Perhaps in the MFC there is some particular staff to do this ...
Regards.
Pavel.
Re: Create window form C++ function using MFC or Win32 API
Code:
HINSTANCE hInst = GetModuleHandle(NULL);
Re: Create window form C++ function using MFC or Win32 API
Thanks Igor,
I've tried already this. hInst isnt NULL and CreateWindow also return non-NULL handler, but when I try to show window
BOOL b_ShowWindowRSLT = ShowWindow(hWnd, SW_SHOWDEFAULT );where hWnd - handler, returned by CreateWindow, it fails - i.e. b_ShowWindowRSLT is FALSE.
I tried also dll filename instead of NULL. The same result...
Regards.
Pavel.
Re: Create window form C++ function using MFC or Win32 API
Re: Create window form C++ function using MFC or Win32 API
The last error - ShowWindow fails.
Re: Create window form C++ function using MFC or Win32 API
Just pay a little bit more attention to the documentation.
If ShowWindow function returns zero (FALSE), means "the window was previously hidden", not "function failed".
Besides, hWnd is a handle (with no final 'r') and not a handler.
1 Attachment(s)
Re: Create window form C++ function using MFC or Win32 API
Ok, you are right. Thanks Ovidiu.
Here is a bit of code, that doesn't work:
Quote:
HWND hWnd = CreateWindow(szAppName, L"title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(L"vpi_win32.dll"), 0 );
vpi_printf("Window handle: %d\n", hWnd);
if(hWnd != NULL)
{
BOOL b_ShowWindowRSLT = ShowWindow(hWnd, SW_SHOWDEFAULT);
while(GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
vpi_printf("pass 3\n");
}
Here is CAD console output (vpi_printf):
Attachment 30811
So, as you can constate, the execution is blocked inside of GetMessage function.
Regards,
Pavel
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Pavel_47
The last error - ShowWindow fails.
Windows classics. The last error is what GetLastError returns. So next time when you're asked about last error please give no meaningless answers. :)
Re: Create window form C++ function using MFC or Win32 API
Quote:
So next time when you're asked about last error please give no meaningless answers
Ok, will keep in mind
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Pavel_47
Code:
HWND hWnd = CreateWindow(szAppName, L"title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(L"vpi_win32.dll"), 0 );
vpi_printf("Window handle: %d\n", hWnd);
if(hWnd != NULL)
{
BOOL b_ShowWindowRSLT = ShowWindow(hWnd, SW_SHOWDEFAULT);
while(GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
vpi_printf("pass 3\n");
}
A few notes on the code:- szAppName - this must be the name of a registered window class. Is it?
- WS_OVERLAPPEDWINDOW - did you try to explicitly specify WS_VISIBLE. Why all that mess with ShowWindow?
- SW_SHOWDEFAULT - did you try SW_SHOWNORMAL or just SW_SHOW?
- GetMessage - this will always block, this is the main intention of using GetMessage. :) If you expected some other behavior, you need some other type of message pump here.
BTW, while(GetMessage(&msg, 0, 0, 0)) is a bad style. GetMessage may return -1 indicating something bad happened, but you're always gonna be locked in looping. As Ovidiu already said, try to pay some more attention to reading MSDN docs.
Re: Create window form C++ function using MFC or Win32 API
Thanks Igor,
I followed your proposition and finally get my window !
Here is code:
Code:
PLI_INT32 vpi_CreateWindow(PLI_BYTE8 *user_data)
{
WNDCLASSEX WindowClass; // Structure to hold our window's attributes
static LPCTSTR szAppName = L"OFWin"; // Define window class name
MSG msg; // Windows message structure
WindowClass.cbSize = sizeof(WNDCLASSEX); // Set structure size
// Redraw the window if the size changes
WindowClass.style = CS_HREDRAW | CS_VREDRAW;
// Define the message handling function
WindowClass.lpfnWndProc = WindowProcedure;
WindowClass.cbClsExtra = 0; // No extra bytes after the window class
WindowClass.cbWndExtra = 0; // structure or the window instance
WindowClass.hInstance = GetModuleHandle(L"vpi_win32.dll"); // Application instance handle
vpi_printf("Instance handle: %d\n", WindowClass.hInstance);
// Set default application icon
WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
// Set window cursor to be the standard arrow
WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
// Set gray brush for background color
WindowClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH));
WindowClass.lpszMenuName = 0; // No menu
WindowClass.lpszClassName = szAppName; // Set class name
WindowClass.hIconSm = 0; // Default small icon
RegisterClassEx(&WindowClass);
HWND hWnd = CreateWindow(szAppName, L"title", WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, GetModuleHandle(L"vpi_win32.dll"), 0 );
vpi_printf("Window handle: %d\n", hWnd);
if(hWnd != NULL)
{
BOOL b_ShowWindowRSLT = ShowWindow(hWnd, SW_SHOW);
//while(GetMessage(&msg, 0, 0, 0))
// DispatchMessage(&msg);
//vpi_printf("pass 3\n");
}
return(0);
}
But to achieve this I commented GetMessage loop. What can be alternative for it ? Unfortunately I'm not programmer, and all this staff I learned/copied from www on-th-fly to get worked my principal project, which is in Verilog.
Regards.
Pavel.
Re: Create window form C++ function using MFC or Win32 API
I think that my function doesn't need GetMessage - the parent CAD window does this job: I could move the window around the screen with GetMessage commented, which proves my guess. Isn't it ?
Re: Create window form C++ function using MFC or Win32 API
I've just tried to do the same using MFC, as creating/processing all of controls with Win32 is complicated. Here is a code that doesn't work. Doesn't work means - nothing happens - non window appears:
Code:
class COurApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
class COurWnd:public CFrameWnd
{
public:
COurWnd()
{
Create(0, L"MFC Application");
}
};
BOOL COurApp::InitInstance(void)
{
m_pMainWnd = new COurWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
return TRUE;
}
PLI_INT32 vpi_CreateWindow(PLI_BYTE8 *user_data)
{
COurApp app;
BOOL aaa = app.InitInstance();
return 0;
}
FYI the CAD tools calls vpi_CreateWindow function.
Any ideas ?
Apart from Win32 and MFC theoretically there is 3rd possibility - WindowsForms. But keeping in mind that this last concept uses CLR, that is unlikely supported by CAD, I won't try this approach.
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Pavel_47
I've just tried to do the same using MFC, as creating/processing all of controls with Win32 is complicated.
Why don't you take a working example, get it compile, run it, and understand why that example works?
Learning how to write a Windows API program shouldn't be done by trying to cobble up code yourself. You should be taking a working example already written by an experienced person and understand the different parts of it -- the creation of the window class, the message loop, the window procedure, etc. Writing a Windows program in a proper way cannot be done (I have yet to see it done) without first getting a working example and learning from the example programs.
There are thousands of these examples all over the Internet. Or get a good book, such as the ones written by Charles Petzold.
For example, the GetMessage() loop is documented in again, thousands of places, and more pointedly, MSDN as looking like this:
Code:
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Does your loop look like this? Look at all of the pieces missing from your example compared to a documented example from MSDN.
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Regards,
Paul McKenzie
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Pavel_47
I've just tried to do the same using MFC, as creating/processing all of controls with Win32 is complicated. Here is a code that doesn't work. Doesn't work means - nothing happens - non window appears:
[...]
Code:
PLI_INT32 vpi_CreateWindow(PLI_BYTE8 *user_data)
{
COurApp app;
BOOL aaa = app.InitInstance();
return 0;
}
Just to mention a little C++ basics detail: app object is locally defined in vpi_CreateWindow function. When it goes out of scope (the function returns), that object is destroyed. So, even something would happen, it happens for a very, very short time.
Quote:
Originally Posted by
Pavel_47
Apart from Win32 and MFC theoretically there is 3rd possibility - WindowsForms. But keeping in mind that this last concept uses CLR, that is unlikely supported by CAD, I won't try this approach.
Sure. To avoid even more painful headaches, in your particular case, keep away of .NET stuff! ;)
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Paul McKenzie
There are thousands of these examples all over the Internet. Or get a good book, such as the ones written by Charles Petzold.
Hello Paul. Thank you for response. If you show me just one, that correspond to my case I will be very grateful. FYI my case is:
- creation of a GUI inside of a DLL
- DLL is called by a particular CAD tool
- the CAD interface for DLL call isn't on my control
Regards
Pavel
Re: Create window form C++ function using MFC or Win32 API
Thanks Ovidiu,
I programmed in C++ about 15 years ago, so some basic things are forgotten.
Finally I've found workaround. Here is code that works (in sense simple window is displayed).
Thanks to all participants !
Best Regards.
Pavel.
Code:
#include "stdafx.h"
#include "vpi_MFC_regular.h"
#include "vpi_user.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Cvpi_MFC_regularApp
BEGIN_MESSAGE_MAP(Cvpi_MFC_regularApp, CWinApp)
END_MESSAGE_MAP()
// Cvpi_MFC_regularApp construction
Cvpi_MFC_regularApp::Cvpi_MFC_regularApp()
{
vpi_printf("Inside of Application Constructor\n");
}
// The one and only Cvpi_MFC_regularApp object
Cvpi_MFC_regularApp theApp;
class CMyWindow : public CFrameWnd
{
CStatic* cs;
public:
CMyWindow();
};
CMyWindow::CMyWindow()
{
Create(NULL, L"MyWindow", WS_VISIBLE, CRect(0,0,200,200));
cs = new CStatic();
cs->Create(L"AAAAAAAAAAAAAA", WS_CHILD|WS_VISIBLE|SS_CENTER, CRect(50, 80, 150, 150), this);
vpi_printf("Inside of Window Constructor\n");
}
// Cvpi_MFC_regularApp initialization
BOOL Cvpi_MFC_regularApp::InitInstance()
{
vpi_printf("Inside of Application InitInstance\n");
CWinApp::InitInstance();
m_pMainWnd = new CMyWindow();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
PLI_INT32 vpi_CreateWindow(PLI_BYTE8 *user_data)
{
vpi_printf("Inside of vpi_CreateWindow\n");
return 0;
}
Re: Create window form C++ function using MFC or Win32 API
Quote:
Originally Posted by
Pavel_47
Hello Paul. Thank you for response. If you show me
just one, that correspond to my case I will be very grateful. FYI my case is:
- creation of a GUI inside of a DLL
- DLL is called by a particular CAD tool
- the CAD interface for DLL call isn't on my control
Can you create a GUI, regardless of whether it is in a DLL or not? You are trying to run a marathon, but have not learned how to walk.
Windows programming cannot be picked up by cobbling code together, and programming experience in whatever language doesn't automatically guarantee you can write a Windows program. You could be a C++ programmer for many years, if you haven't done event-driven programming, it is going to be brand new to you, and that takes time to learn. To learn Windows programming properly requires knowing and running working examples, regardless of what your final goal is.
If you can't do the basics, how are you going to accomplish anything from there? You create the GUI and you display the window and wait for events to be processed by the window procedure. It is no different for an app than it is for a DLL. The only difference of note is that the resources to create the Window would normally reside in the DLL's resources and not the main app's resources.
As for real-life examples, do you own a TWAIN device or scanner? Well, they work exactly the same way as you described. The user interface is implemented in a DLL provided by the manufacturer, and this GUI is initiated by the application (more exactly, the TWAIN manager).
But to get to this stage, you need to be a solid Windows programmer, or at the very least, know the fundamentals enough to not have to make serioous errors such as writing incorrect message loops, never calling GetLastError() if there is an issue, etc. All of these mistakes are corrected by looking at working code and studying it properly.
Regards,
Paul McKenzie
Re: Create window form C++ function using MFC or Win32 API
is this really for twain scanning code ???