scottme Posted February 14, 2006 Report Posted February 14, 2006 Hi all (especially Pete!) I am having a little problem with coding my module Dialog app. I think I have it set up OK, but I am having some hassle setting up the timer with the SetTimer function. Basically, my code is: ..... // Handles WNDPROC oldWndProc; // The standard window procedure used by the flight simulator HWND hFSimWindow; // Flight simulator main window handle HWND hwndDlg = NULL;// Handle for My dialog window HINSTANCE g_hInst; // Handle for the mainDLL call #define MENU_ENTRY "VSM Modules" #define ID_MY_MENUITEM1 40001 // My Dialog Routine BOOL CALLBACK FSBDlgProc(HWND hwndDlg, UINT Message, WPARAM wParam, LPARAM lParam) { // Set the timer SetTimer( hwndDlg, // handle to FSBridge IDT_TIMER1, // timer identifier 20, // 1/1000th seconds: 10000 = 10 second interval (TIMERPROC) NULL); // no timer callback switch(Message) { case WM_INITDIALOG: { //Initialise FSUIPC etc return 0; } case WM_TIMER: { // Main Code - Get Sim Values using FSUIPC // Display data to Static Text in the Dialog box return 0; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_CANCEL: PostMessage(hwndDlg, WM_CLOSE, 0, 0); break; case ID_FILE_EXIT: PostMessage(hwndDlg, WM_CLOSE, 0, 0); break; } break; case WM_CLOSE: { DestroyWindow(hwndDlg); } break; case WM_DESTROY: { FSUIPC_Close(); hwndDlg = NULL; KillTimer(hwndDlg, IDT_TIMER1); } break; default: return FALSE; } return TRUE; } /** * Main window procedure that is called by the flight simulator to process * incoming window messages. */ LRESULT CALLBACK FSimWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_NCPAINT: { HMENU hMenu, hMyMenu; hMenu = GetMenu(hwnd); //Copy the handle of the Menu item if (hMenu != NULL) { int i; // Look for our menu entry in the main menu. for (i = 0; i < GetMenuItemCount(hMenu); i++) { char buf[128]; GetMenuString(hMenu, i, buf, 128, MF_BYPOSITION); if (strcmp(buf, MENU_ENTRY) == 0) { // It is already here, we do not need to add it again break; } } // end of loop if (i < GetMenuItemCount(hMenu)) { // It is already here, we do not need to add it again break; } /* Create new menu. NOTE: It seems that this will be * reached more times, so we cannot save the handle, because * in such case it could be destroyed and we will not have * any access to it in the simulator. */ hMyMenu = CreateMenu(); AppendMenu(hMyMenu, MF_STRING | MF_ENABLED, ID_MY_MENUITEM1, "&FSBridge"); // add the created menu to the main menu AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hMyMenu, MENU_ENTRY); } } break; case WM_PAINT: { } break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_MY_MENUITEM1: { // Only create Dialog if not existing if (!IsWindow(hwndDlg)) { hwndDlg = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_FSBRIDGE), hwnd, FSBDlgProc); ShowWindow(hwndDlg, SW_SHOW); } } break; } //break; return TRUE; } // Call the original window procedure to handle all other messages return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam); } /** * Entry point of the DLL. */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) { g_hInst = hInstDLL; //copies the hInstDLL into "instance" for use it into all the APIs switch (fdwReason) { case DLL_PROCESS_ATTACH: // Finds the window of title "FS98MAIN" (FS) and returns the handle hFSimWindow = FindWindow("FS98MAIN", NULL); // Gets the handle of the standard FS proceedure oldWndProc = (WNDPROC)SetWindowLong(hFSimWindow, GWL_WNDPROC, (LONG)FSimWindowProc); break; } return TRUE; } Where do I place the SetTimer call? If I place it at the start of FSimWindowProc, FS stops painting the window. If I place where shown at the start of the Dialog procedure, it gets reset when any message gets sent to the Dialog procedure. A better place seems to be in the WM_PAINT section of the main FSimWindowProc - any better suggestions? Overall, is this the most efficient way of displaying dynamic FSUIPC generated text in an internal FS Dialog module at about the same frequency as the FS Framerate (about 20-40fps)? Also, if I close the Dialog box, it will not reopen/re-initialise. Any ideas why? I presume it is OK to de-initialise using the Dialog procedure (WM_CLOSE) and not FSAPI module_deinit? I am also having some runtime / stack issues around the transfering of data from the FSUIPC_PROCESS calls, but I will get to that next... Apologies about the hefty post, but any helpful hints would be hugely appreciated. Cheers, Scott.
Pete Dowson Posted February 14, 2006 Report Posted February 14, 2006 Where do I place the SetTimer call? If I place it at the start of FSimWindowProc, FS stops painting the window. If I place where shown at the start of the Dialog procedure, it gets reset when any message gets sent to the Dialog procedure. The most obvious place in in the INIDIALOG call in the dialogue procedure, surely. That's when the dialogue window handle is first valid and it is called just the once, when the dialogue is created. Overall, is this the most efficient way of displaying dynamic FSUIPC generated text in an internal FS Dialog module at about the same frequency as the FS Framerate (about 20-40fps)? Well, not as efficient as a genuine FS gauge, of ocurse, which is using all of the ready built-in graphics stuff in FS and is getting called when its variables change no matter what the frame rate. Also, if I close the Dialog box, it will not reopen/re-initialise. Any ideas why? I presume it is OK to de-initialise using the Dialog procedure (WM_CLOSE) and not FSAPI module_deinit? If you are closing the FSUIPC link in the dialog, you should be opening it there too (in the INITDIALOG). If you open the FSUIPC link upon Module_Init, then close it in Module-Deinit. Symmetry is wonderful, isn't it? ;-). Bearing in mind that all the FSUIPC_Open2 and FSUIPC_Close are doing is providing and removing (respectively) a fixed address of an area in which you will pass requests, I would have thought the simplest thing would be to do it on Init and Deinit. Regards, Pete
scottme Posted February 18, 2006 Author Report Posted February 18, 2006 Thanks once again Pete, that worked a treat! I am having issues read the Altitude from 0x0570 (also TAS from 0x02B8) My relevant code is DWORD dwSize = 2048; BYTE pMem [2048]; if (FSUIPC_Open2(SIM_ANY, &dwResult, pMem, dwSize)) { etc... In a different module: int ReadInitFS(double *FS_LatLong, float *FS_MainStates) { DWORD dwResult; __int64 FS_LatLongTemp[3] = {0}; __int32 FS_MainStatesTemp[4] = {0}; // Get location & State //FSUIPC_Read(0x0560, 8, &FS_LatLongTemp[1], &dwResult);//Lat //FSUIPC_Read(0x0568, 8, &FS_LatLongTemp[2], &dwResult);//Long FSUIPC_Read(0x0570, 8, &FS_LatLongTemp[3], &dwResult);//Alt //FSUIPC_Read(0x057C, 4, &FS_MainStatesTemp[1], &dwResult);//Phi //FSUIPC_Read(0x0578, 4, &FS_MainStatesTemp[2], &dwResult);//Theta //FSUIPC_Read(0x0580, 4, &FS_MainStatesTemp[3], &dwResult);//Psi //FSUIPC_Read(0x02B8, 4, &FS_MainStatesTemp[4], &dwResult);//TAS FSUIPC_Process(&dwResult); // Process the request(s) // Change FS to Real Units: Lat Long Alt FS_LatLong[1] = (double)FS_LatLongTemp[1] * (90.0 / (10017500.0 * 65536.0 * 65536.0 )); FS_LatLong[2] = (double)FS_LatLongTemp[2] * (360.0 / (65536.0 * 65536.0 * 65536.0 * 65536.0)); FS_LatLong[3] = (double)FS_LatLongTemp[3] / (65536.0 * 65536.0); // Phi, Theta, Psi FS_MainStates[1] = (float)FS_MainStatesTemp[1] * 360.0 / (65536.0 * 65536.0); FS_MainStates[2] = (float)FS_MainStatesTemp[2] * 360.0 / (65536.0 * 65536.0); FS_MainStates[3] = (float)FS_MainStatesTemp[3] * 360.0 / (65536.0 * 65536.0); FS_MainStates[4] = (float)FS_MainStatesTemp[4] / 128.0 / (float) MPS2KTS; return dwResult; } I can read Latitude, Longitude and the Euler angles perfectly. As soon as I try reading Altitude or TAS, I get run-time stack errors about dwResult and FS_LatLongTemp / FS_MainStatesTemp. I checked out FSInterogate, but it didn't tell me how Altitude differs from Lat/Long. I also tried pulling Altitude and TAS out of the integer matrices and the run-time error dissappeared, but I am getting a value which changes with bank angle! I wold very much appreciate any help!
Pete Dowson Posted February 18, 2006 Report Posted February 18, 2006 __int64 FS_LatLongTemp[3] = {0}; __int32 FS_MainStatesTemp[4] = {0}; ... FSUIPC_Read(0x0570, 8, &FS_LatLongTemp[3], &dwResult);//Alt ... As soon as I try reading Altitude or TAS, I get run-time stack errors about dwResult and FS_LatLongTemp / FS_MainStatesTemp. I'm not surprised. You defined FS_LatLongTemp as having 3 elements, then try to read the Alt into the 4th one! This is an elementary programming error -- in C/C++ array elements are numbered from 0, not 1. Once you get used to the language you'll never make this mistake again! ;-) Regards Pete
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now