FSX Popup windows: Difference between revisions

From FSDeveloper Wiki
Jump to navigationJump to search
(New page: {{Infobox-Applicable-FSVersion | FSXI = false | FSXA = false | FSX = false | FS2004 = false | FS2002 = false | XP10 = false | XP9 = false }} Here is a short tutorial on how to create p...)
 
No edit summary
Line 1: Line 1:
{{Infobox-Applicable-FSVersion
{{Infobox-Applicable-FSVersion
| FSXI = false
| FSXI = false
| FSXA = false
| FSXA = true
| FSX = false
| FSX = false
| FS2004 = false
| FS2004 = false
Line 14: Line 14:
First off, in your header file, add the following declarations:
First off, in your header file, add the following declarations:


[CODE]
#include <windows.h>
#include <process.h>


bool CreateWin();
#include <windows.h>
bool ExitWin();
#include <process.h>
DWORD WINAPI WinThread(LPVOID lpParam);
bool RegisterWin();
bool CreateWin();
LRESULT CALLBACK WinQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
bool ExitWin();
//Replace Win with any identifier name you want
DWORD WINAPI WinThread(LPVOID lpParam);
[/CODE]
bool RegisterWin();
LRESULT CALLBACK WinQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
//Replace Win with any identifier name you want


Then, in your cpp file, create the thread that the window message cue will be run from.
Then, in your cpp file, create the thread that the window message cue will be run from.


[CODE]
bool CreateWin()
bool CreateWin()
{
{
CreateThread(0, NULL, WinThread, NULL, NULL, NULL);
CreateThread(0, NULL, WinThread, NULL, NULL, NULL);
return true;
return true;
//returns true so that you can know that you have sent the command to open the new window
//returns true so that you can know that you have sent the command to open the new window
}
}
[/CODE]


Also create a function to call to shut down the window(This window does come with a little red box in the upper right corner so this function is just an alternative(also can be called on shutdown)).
Also create a function to call to shut down the window(This window does come with a little red box in the upper right corner so this function is just an alternative(also can be called on shutdown)).


[CODE]
bool ExitWin()
bool ExitWin()
{
{
SendMessage(hwnd, WM_CLOSE, 0, 0);
SendMessage(hwnd, WM_CLOSE, 0, 0);
return false;
return false;
}
}
[/CODE]


Next is your function to register the class. Note that i have made it a template of the FS98FLOAT class to save some code lines.
Next is your function to register the class. Note that i have made it a template of the FS98FLOAT class to save some code lines.


[CODE]
bool RegisterWin()
bool RegisterWin()
{
{
WNDCLASSW wc;
WNDCLASSW wc;
memset(&wc,0,sizeof(WNDCLASS));
memset(&wc,0,sizeof(WNDCLASS));
if(GetClassInfo(NULL, L"FS98FLOAT", &wc))
if(GetClassInfo(NULL, L"FS98FLOAT", &wc))
{
{
wc.lpszClassName = L"MYFLOAT";//Choose your class name
wc.lpszClassName = L"MYFLOAT";//Choose your class name
wc.hInstance = GetModuleHandle(L"MY_DLL.dll");//place your dll name here
wc.hInstance = GetModuleHandle(L"MY_DLL.dll");//place your dll name here
wc.lpfnWndProc = (WNDPROC) WinQueue;//Your message que function
wc.lpfnWndProc = (WNDPROC) WinQueue;//Your message que function
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
if(RegisterClass(&wc))
if(RegisterClass(&wc))
return true;
return true;
else
else
return false;
return false;
}
}
else
else
return false;
return false;
}
}
[/CODE]


And now your thread function
And now your thread function


[CODE]
DWORD WINAPI ACMProc(LPVOID lpParam)
DWORD WINAPI ACMProc(LPVOID lpParam)
{
{
MSG msg;
MSG msg;
RegisterWin();//Register the class
RegisterWin();//Register the class
hwnd = CreateWindowEx(
hwnd = CreateWindowEx(
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE,//necessary styles etc
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE,//necessary styles etc
L"MYFLOAT", // Your class name L"My Window",//Window caption
L"MYFLOAT", // Your class name L"My Window",//Window caption
WS_CAPTION | WS_POPUP | WS_CLIPSIBLINGS | WS_SYSMENU | WS_THICKFRAME,//necessary styles etc
WS_CAPTION | WS_POPUP | WS_CLIPSIBLINGS | WS_SYSMENU | WS_THICKFRAME,//necessary styles etc
0,0, 800,600,//Window position/Dimensions
0,0, 800,600,//Window position/Dimensions
FindWindow(L"FS98MAIN", L"Microsoft Flight Simulator X"),//The Parent window
FindWindow(L"FS98MAIN", L"Microsoft Flight Simulator X"),//The Parent window
NULL,
NULL,
GetModuleHandle(L"My_DLL.dll"),
GetModuleHandle(L"My_DLL.dll"),
NULL );
NULL );
ShowWindow (hwnd, SW_SHOWNORMAL);//Shows the window
ShowWindow (hwnd, SW_SHOWNORMAL);//Shows the window
while (GetMessage (&msg, NULL, 0, 0))
while (GetMessage (&msg, NULL, 0, 0))
{
{
TranslateMessage(&msg);
TranslateMessage(&msg);
DispatchMessage(&msg);
DispatchMessage(&msg);
}
}
return 1;
return 1;
}
}
[/CODE]


And finally, the message cue. You can do pretty much whatever you want from here out
And finally, the message cue. You can do pretty much whatever you want from here out


[CODE]
LRESULT CALLBACK ACMQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK ACMQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
{
switch(message)
switch(message)
{
{
case WM_CREATE: // sent by the windows system just before the window will be displayed the first time
case WM_CREATE: // sent by the windows system just before the window will be displayed the first time
// here is the best location to prepare your window i.e. connecting to SimConnect
break;
case WM_ERASEBKGND:     // sent by windows if t he entire window will be renewed.
break; // if y ou create your own background, do it here in and return (1) instead using 'break'
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
wchar_t *WinOutput[] = {{L"Hello World!"},{L"This window was created  out of a DLL."}};
hdc = BeginPaint(hwnd, &ps);  // now we have a valid device context to modify the window's content
TextOut(hdc,20,20,WinOutput[0],wcslen(WinOutput[0]));
MoveToEx(hdc,20,40,NULL);
LineTo(hdc,120,40);
TextOut(hdc,20,60,WinOutput[1],wcslen(WinOutput[1]));
// do all drawing of your window  here in
EndPaint(hwnd,&ps);
}
break;
case WM_DESTROY: // sent by the windows system just before the window will be destroyed
// disconnect from SimConnect out of this message
break;
case WM_CLOSE:
break;
}
return (DefWindowProcA(hwnd, message, wParam, lParam));
}


// here is the best location to prepare your window i.e. connecting to SimConnect
break;
case WM_ERASEBKGND:     // sent by windows if the entire window will be renewed.
break; // if you create your own background, do it here in and return (1) instead using 'break'
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
wchar_t *WinOutput[] = {{L"Hello World!"},{L"This window was created out of a DLL."}};
hdc = BeginPaint(hwnd, &ps);  // now we have a valid device context to modify the window's content
TextOut(hdc,20,20,WinOutput[0],wcslen(WinOutput[0]));
MoveToEx(hdc,20,40,NULL);
LineTo(hdc,120,40);
TextOut(hdc,20,60,WinOutput[1],wcslen(WinOutput[1]));
// do all drawing of your window  here in
EndPaint(hwnd,&ps);
}
break;
case WM_DESTROY: // sent by the windows system just before the window will be destroyed
// disconnect from SimConnect out of this message
break;
case WM_CLOSE:
Vd->INIS->AcmWin = false;
break;
}
return (DefWindowProcA(hwnd, message, wParam, lParam));
}
[/CODE]


Enjoy!!
Enjoy!!


[[category:Panel and Gauge Design]]
[[category:Panel and Gauge Design]]

Revision as of 16:52, 24 February 2013


Here is a short tutorial on how to create popup windows from a C++ gauge or SimConnect module dll. Do note that i will not be going into where to execute the creation functions from the gauge or SimConnect dll.

First off, in your header file, add the following declarations:


#include <windows.h>
#include <process.h>

bool CreateWin();
bool ExitWin();
DWORD WINAPI WinThread(LPVOID lpParam);
bool RegisterWin();
LRESULT CALLBACK WinQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
//Replace Win with any identifier name you want

Then, in your cpp file, create the thread that the window message cue will be run from.

bool CreateWin()
{
	CreateThread(0, NULL, WinThread, NULL, NULL, NULL);
	return true;
//returns true so that you can know that you have sent the command to open the new window
}

Also create a function to call to shut down the window(This window does come with a little red box in the upper right corner so this function is just an alternative(also can be called on shutdown)).

bool ExitWin()
{
	SendMessage(hwnd, WM_CLOSE, 0, 0);
	return false;
}

Next is your function to register the class. Note that i have made it a template of the FS98FLOAT class to save some code lines.

bool RegisterWin()
{
	WNDCLASSW wc;	
	memset(&wc,0,sizeof(WNDCLASS));
	if(GetClassInfo(NULL, L"FS98FLOAT", &wc))
	{
		wc.lpszClassName = L"MYFLOAT";//Choose your class name
		wc.hInstance = GetModuleHandle(L"MY_DLL.dll");//place your dll name here
		wc.lpfnWndProc = (WNDPROC) WinQueue;//Your message que function
		wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
		if(RegisterClass(&wc))
			return true;
		else
			return false;
	}
	else
		return false;
}

And now your thread function

DWORD WINAPI ACMProc(LPVOID lpParam)
{
	MSG msg;
	RegisterWin();//Register the class
	hwnd = CreateWindowEx(
				WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR |  WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE,//necessary styles etc
				L"MYFLOAT", // Your class name				 				L"My Window",//Window caption
				WS_CAPTION | WS_POPUP | WS_CLIPSIBLINGS | WS_SYSMENU |  WS_THICKFRAME,//necessary styles etc
				0,0, 800,600,//Window position/Dimensions
				FindWindow(L"FS98MAIN", L"Microsoft Flight Simulator X"),//The Parent  window
				NULL,
				GetModuleHandle(L"My_DLL.dll"),
				NULL );
	ShowWindow (hwnd, SW_SHOWNORMAL);//Shows the window
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 1;
}

And finally, the message cue. You can do pretty much whatever you want from here out

LRESULT CALLBACK ACMQueue(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_CREATE:							// sent by the  windows system just before the window will be displayed the first time

			// here is the best location to prepare your window i.e. connecting to SimConnect

			break;
		case WM_ERASEBKGND:					    // sent by windows if t he entire window will be renewed.
			break;								// if y ou create your own background, do it here in and return (1) instead using 'break'
		case WM_PAINT:
			{
				PAINTSTRUCT ps;
				HDC hdc;
				wchar_t *WinOutput[] = {{L"Hello World!"},{L"This window was created  out of a DLL."}};

hdc = BeginPaint(hwnd, &ps); // now we have a valid device context to modify the window's content

				TextOut(hdc,20,20,WinOutput[0],wcslen(WinOutput[0]));
				MoveToEx(hdc,20,40,NULL);
				LineTo(hdc,120,40);
				TextOut(hdc,20,60,WinOutput[1],wcslen(WinOutput[1]));
				// do all drawing of your window  here in

				EndPaint(hwnd,&ps);
			}
			break;
		case WM_DESTROY:		// sent by the windows system just before the window will be destroyed
								// disconnect from SimConnect out of this message
			break;
		case WM_CLOSE:
			break;
	}
	return (DefWindowProcA(hwnd, message, wParam, lParam));

}


Enjoy!!