%% options copyright owner = Dirk Krause copyright year = 2017 license = bsd %% wx-gui type = frame contents = mainSizer icon = wxdkscrsz_icon status bar = 1 sTexts[8] menu bar = mbMain [wxMenuBar mbMain] contents = menuFile contents = menuHelp [wxMenu menuFile] text = sTexts[0] contents = miFileExit [wxMenuItem miFileExit] id = ScreenSizeFrame_Quit text = sTexts[1] tip = sTexts[2] [wxMenu menuHelp] text = sTexts[3] contents = miHelpAbout contents = miHelpContents [wxMenuItem miHelpAbout] id = ScreenSizeFrame_Help_About text = sTexts[4] tip = sTexts[5] [wxMenuItem miHelpContents] id = ScreenSizeFrame_Help_Contents text = sTexts[6] tip = sTexts[7] [wxBoxSizer mainSizer] direction = horizontal contents = $space(10) contents = verticalSizer contents = $space(10) [wxBoxSizer verticalSizer] direction = vertical grow = yes proportion = 1 contents = $space(10) contents = contentsSizer contents = $space(10) [wxGridBagSizer contentsSizer] grid = 5 5 contents = lOldSize 0 0 1 2 centered-x contents = lOldWidth +1 0 1 1 right contents = vOldWidth . 1 1 1 left contents = lOldHeight +1 0 1 1 right contents = vOldHeight . 1 1 1 left contents = $space(1,5) +1 0 1 1 left contents = lNewSize +1 0 1 2 centered-x contents = lNewWidth +1 0 1 1 right contents = vNewWidth . 1 1 1 left contents = lNewHeight +1 0 1 1 right contents = vNewHeight . 1 1 1 left contents = $space(1,5) +1 0 1 1 left contents = lResult +1 0 1 2 centered-x contents = lSsc +1 0 1 1 right contents = lSsr . 1 1 1 left [wxStaticText lOldSize] text = sTexts[25] text style = centered [wxStaticText lOldWidth] text = sTexts[26] text style = right [wxStaticText vOldWidth] text = sTexts[28] text style = left [wxStaticText lOldHeight] text = sTexts[27] text style = right [wxStaticText vOldHeight] text = sTexts[28] text style = left [wxStaticText lNewSize] text = sTexts[29] text style = centered [wxStaticText lNewWidth] text = sTexts[26] text style = right [wxStaticText vNewWidth] text = sTexts[28] text style = left [wxStaticText lNewHeight] text = sTexts[27] text style = right [wxStaticText vNewHeight] text = sTexts[28] text style = left [wxStaticText lResult] text = sTexts[30] text style = centered [wxStaticText lSsc] text = sTexts[13] text style = right [wxStaticText lSsr] text = sTexts[14] text style = left %% header start #include enum { /** Set new screen size. */ ACTION_SET_SCREEN_SIZE = 0 , /** Toggle between normal and alternative size. */ ACTION_TOGGLE_SCREEN_SIZE , ACTION_REPORT_NO_ARGS_NO_SETTINGS }; %% class start class ScreenSizeFrame : public Dk4WxFrame { private: /** Event table for frame. */ DECLARE_EVENT_TABLE() protected: /** Controller to start activity at first idle event. */ Dk4WxAutostartController oAsc; /** Color to indicate success. */ wxColour cGreen; /** Color to indicate failure. */ wxColour cRed; /** Localized texts. */ wxChar const * const *sTexts; /** Non-localized texts. */ wxChar const * const *sNlWx; /** Non-localized texts. */ dkChar const * const *sNlDk; /** Private copy of the argv arguments. */ wxChar **ppArgv; /* __CHANGE__ 011: Add further member variables. */ /** Private copy of the argc arguments. */ int iArgc; /** Flag: Process idle events. */ bool bActive; %% class end private: void ShowUnusableText(const wxChar *str); protected: /** Do the real work in the screen size change. @param ulp Address of array containing screen sizes. @param action Action to perform (set or toggle). @return True on success, false on error. */ bool ModifyScreenSize(const unsigned long *ulp, int action); public: /** Constructor. @param wxid Window ID. @param applicationHelper Application helper object. @param hc Help controller for online help. @param argc Number of command line arguments. @param argv Command line arguments array. @param localizedTexts Localized wxChar texts. @param nlWx Non-localized wxChar texts. @param nlDk Non-localized dkChar texts. */ ScreenSizeFrame( int wxid, Dk4WxApplicationHelper *applicationHelper, Dk4WxHelpController *hc, int argc, wxChar **argv, wxChar const * const *localizedTexts, wxChar const * const *nlWx, dkChar const * const *nlDk ); /** Destructor. */ ~ScreenSizeFrame(); /** Check whether we can close the window. @param isLast Flag: Last main window to close. */ bool CanClose(bool isFinal); /** Handler for File/Exit. @param event Event to process. */ void OnQuit(wxCommandEvent & event); /** Handler for Help/About. @param event Event to process. */ void OnAbout(wxCommandEvent & event); /** Handler for Help/Contents. @param event Event to process. */ void OnHelpContents(wxCommandEvent & event); /* __CHANGE__ 008: Remove OnIdle if no idle processing required. */ /** Handler for idle events. */ void OnIdle(wxIdleEvent & event); /* __CHANGE__ 017: Event handlers for further events. */ /* __CHANGE__ 014: Add further methods. */ /** Change the screen size. @return True on success, false on error. */ bool ChangeScreenSize(void); }; %% header end /* vim: set ai sw=4 ts=4 : */ %% module start #define AUTO_EXIT_ONLY_ON_SUCCESS 1 #include "dk4mem.h" #include "wxdkscrsz.h" #include #include "dk4maoxd.h" #if !defined(__WXMSW__) #include "wxdkscrsz.xpm" #endif $!trace-include static const wxChar * const settingsNames[] = { $!string-table macro=wxT screen.size.normal.width screen.size.normal.height screen.size.alternative.width screen.size.alternative.height $!end }; /* __CHANGE__ 017: Add further events. */ /* __CHANGE__ 008: Remove OnIdle if no idle processing required. */ BEGIN_EVENT_TABLE(ScreenSizeFrame, wxFrame) EVT_MENU(ScreenSizeFrame_Quit, ScreenSizeFrame::OnQuit) EVT_MENU(ScreenSizeFrame_Help_About, ScreenSizeFrame::OnAbout) EVT_MENU(ScreenSizeFrame_Help_Contents, ScreenSizeFrame::OnHelpContents) EVT_IDLE(ScreenSizeFrame::OnIdle) END_EVENT_TABLE() %% constructor start ScreenSizeFrame::ScreenSizeFrame( int wxid, Dk4WxApplicationHelper *applicationHelper, Dk4WxHelpController *hc, int argc, wxChar **argv, wxChar const * const *localizedTexts, wxChar const * const *nlWx, dkChar const * const *nlDk ) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid), cGreen(0, 127, 0), cRed(127, 0, 0) { /* __CHANGE__ 012: Add further local variables. */ /* __CHANGE__ 012: Initialize further local variables. */ sTexts = localizedTexts; sNlWx = nlWx; sNlDk = nlDk; #if defined(__WXMSW__) wxIcon wxdkscrsz_icon(sNlWx[4]); #else wxIcon wxdkscrsz_icon(xpm_wxdkscrsz); #endif /* __CHANGE__ 011: Initialize further class members. */ bActive = true; iArgc = argc; ppArgv = argv; %% constructor end if(dkctGUILayoutOK) { SetTitle(nlWx[0]); #if 0 RestorePosition(); #endif oAsc.SetAutoStart(true); oAsc.SetAutoExit(true); } /* __CHANGE__ 012: Release resources allocated by local variables. */ } %% module end ScreenSizeFrame::~ScreenSizeFrame() { /* __CHANGE__ 011: Release resources allocated by further class members. */ } bool ScreenSizeFrame::CanClose(bool isLast) { bool back = true; /* __CHANGE__ 013: Check for unsaved data. */ return back; } void ScreenSizeFrame::OnQuit(wxCommandEvent & event) { Close(); } void ScreenSizeFrame::OnAbout(wxCommandEvent & event) { wxString text(wxT("")); wxString title(wxT("")); /* Construct message text. */ text.Append(sNlWx[0]); text.Append(sNlWx[7]); text.Append(sNlWx[1]); text.Append(sNlWx[8]); text.Append(sTexts[9]); text.Append(sNlWx[2]); text.Append(sNlWx[8]); text.Append(sNlWx[8]); text.Append(sTexts[11]); text.Append(sNlWx[8]); text.Append(sNlWx[9]); text.Append(sNlWx[8]); text.Append(sNlWx[8]); text.Append(sTexts[12]); text.Append(sNlWx[8]); text.Append(sNlWx[10]); text.Append(sNlWx[8]); text.Append(sNlWx[11]); text.Append(sNlWx[8]); text.Append(sNlWx[12]); text.Append(sNlWx[8]); text.Append(sNlWx[13]); text.Append(sNlWx[8]); text.Append(sNlWx[14]); text.Append(sNlWx[8]); text.Append(sNlWx[15]); text.Append(sNlWx[8]); /* Construct dialog box title. */ title.Append(sTexts[10]); title.Append(sNlWx[0]); /* Show dialog box. */ wxMessageBox(text, title); /* __CHANGE__ 019: Create better about box. */ } void ScreenSizeFrame::OnHelpContents(wxCommandEvent & event) { DisplayContents(); } /* __CHANGE__ 017: Event handlers for further events. */ /* __CHANGE__ 014: Implementation of further methods. */ #if DK4_ON_WINDOWS /** Current device mode. */ static DEVMODE devmode; /** New device mode. */ static DEVMODE newmode; #endif bool ScreenSizeFrame::ModifyScreenSize(const unsigned long *ulp, int action) { wxChar b1[64]; wxChar b2[64]; wxChar b3[64]; wxChar b4[64]; #if DK4_ON_WINDOWS DWORD dmfm = (DM_PELSWIDTH | DM_PELSHEIGHT); DWORD dwfl = 0; LONG res = 0L; #endif bool back = false; dk4ma_write_wx_decimal_unsigned( b1, DK4_SIZEOF(b1,wxChar), (dk4_um_t)(ulp[0]), 0, NULL ); dk4ma_write_wx_decimal_unsigned( b2, DK4_SIZEOF(b2,wxChar), (dk4_um_t)(ulp[1]), 0, NULL ); dk4ma_write_wx_decimal_unsigned( b3, DK4_SIZEOF(b3,wxChar), (dk4_um_t)(ulp[2]), 0, NULL ); dk4ma_write_wx_decimal_unsigned( b4, DK4_SIZEOF(b4,wxChar), (dk4_um_t)(ulp[3]), 0, NULL ); switch (action) { case ACTION_TOGGLE_SCREEN_SIZE : { vOldWidth->SetLabel(b3); vOldHeight->SetLabel(b4); vNewWidth->SetLabel(b1); vNewHeight->SetLabel(b2); } break; default : { vNewWidth->SetLabel(b1); vNewHeight->SetLabel(b2); } break; } Refresh(); Update(); #if DK4_ON_WINDOWS SecureZeroMemory(&devmode, sizeof(DEVMODE)); SecureZeroMemory(&newmode, sizeof(DEVMODE)); if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode)) { if (dmfm == (dmfm & (devmode.dmFields))) { DK4_MEMCPY(&newmode, &devmode, sizeof(DEVMODE)); dk4ma_write_wx_decimal_unsigned( b1, DK4_SIZEOF(b1,wxChar), (dk4_um_t)(devmode.dmPelsWidth), 0, NULL ); dk4ma_write_wx_decimal_unsigned( b2, DK4_SIZEOF(b2,wxChar), (dk4_um_t)(devmode.dmPelsHeight), 0, NULL ); vOldWidth->SetLabel(b1); vOldHeight->SetLabel(b2); Refresh(); Update(); switch (action) { case ACTION_TOGGLE_SCREEN_SIZE : { if (ulp[0] == devmode.dmPelsWidth) { if (ulp[1] == devmode.dmPelsHeight) { newmode.dmPelsWidth = ulp[2]; newmode.dmPelsHeight = ulp[3]; vOldWidth->SetLabel(b1); vOldHeight->SetLabel(b2); vNewWidth->SetLabel(b3); vNewHeight->SetLabel(b4); Refresh(); Update(); } else { newmode.dmPelsWidth = ulp[0]; newmode.dmPelsHeight = ulp[1]; } } else { newmode.dmPelsWidth = ulp[0]; newmode.dmPelsHeight = ulp[1]; } } break; default : { newmode.dmPelsWidth = ulp[0]; newmode.dmPelsHeight = ulp[1]; } break; } newmode.dmFields |= dmfm; res = ChangeDisplaySettingsEx(NULL, &newmode, NULL, dwfl, NULL); if (DISP_CHANGE_SUCCESSFUL == res) { back = true; } else { /* ERROR: Failed to change screen size */ wxMessageBox( sTexts[20], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); } } else { /* ERROR: Failed to retrieve current settings */ wxMessageBox( sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); } } else { /* ERROR: Failed to retrieve current settings */ wxMessageBox( sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); } #else wxMessageBox( sTexts[21], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); back = false; #endif return back; } void ScreenSizeFrame::ShowUnusableText(const wxChar *str) { wxString s(sTexts[22]); s.Append(str); s.Append(sTexts[23]); wxMessageBox(s, sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)); } bool ScreenSizeFrame::ChangeScreenSize(void) { const wxChar *ep = NULL; long lv[] = { 0L, 0L, 0L, 0L }; unsigned long ulv[] = { 0UL, 0UL, 0UL, 0UL }; int action = ACTION_SET_SCREEN_SIZE; int res = 0; bool back = false; bool found = false; $? "+ ScreenSizeFrame::ChangeScreenSize" switch (iArgc) { case 5 : { back = true; ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL); if (0 == res) { back = false; ShowUnusableText(ppArgv[1]); } if (back) { ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL); if (0 == res) { ShowUnusableText(ppArgv[2]); back = false; } } if (back) { ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[2]),ppArgv[3],&ep,1,NULL); if (0 == res) { ShowUnusableText(ppArgv[3]); back = false; } } if (back) { ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[3]),ppArgv[4],&ep,1,NULL); if (0 == res) { ShowUnusableText(ppArgv[4]); back = false; } } if (back) { back = ModifyScreenSize(ulv, ACTION_TOGGLE_SCREEN_SIZE); } } break; case 3 : { back = true; ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL); if (0 == res) { ShowUnusableText(ppArgv[1]); back = false; } if (back) { ep = NULL; res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL); if (0 == res) { ShowUnusableText(ppArgv[2]); back = false; } } if (back) { back = ModifyScreenSize(ulv, ACTION_SET_SCREEN_SIZE); } } break; case 1 : { action = ACTION_REPORT_NO_ARGS_NO_SETTINGS; if (pAppHelp->GetMultiple(settingsNames, lv, 4)) { if (0L < lv[0]) { if (0L < lv[1]) { if (0L < lv[2]) { if (0L < lv[3]) { ulv[0] = (unsigned long)(lv[0]); ulv[1] = (unsigned long)(lv[1]); ulv[2] = (unsigned long)(lv[2]); ulv[3] = (unsigned long)(lv[3]); found = true; back = ModifyScreenSize( ulv, ACTION_TOGGLE_SCREEN_SIZE ); } } else { ulv[0] = (unsigned long)(lv[0]); ulv[1] = (unsigned long)(lv[1]); found = true; back = ModifyScreenSize( ulv, ACTION_SET_SCREEN_SIZE ); } } } } else { } if (!(found)) { wxMessageBox( sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); } } break; default : { wxMessageBox( sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR) ); } break; } finished: if (back) { lSsr->SetLabel(sTexts[16]); lSsr->SetForegroundColour(cGreen); } else { lSsr->SetLabel(sTexts[17]); lSsr->SetForegroundColour(cRed); } Refresh(); Update(); $? "- ScreenSizeFrame::ChangeScreenSize %d", (back ? 1 : 0) return back; } /* __CHANGE__ 008: Remove OnIdle if no idle processing required. */ void ScreenSizeFrame::OnIdle(wxIdleEvent & event) { #if AUTO_EXIT_ONLY_ON_SUCCESS bool bSuccess; #endif $? "+ ScreenSizeFrame::OnIdle" /* __CHANGE__ */ if (bActive) { switch (oAsc.GetReaction()) { #if 0 case DK4WX_AUTOSTART_REACTION_IGNORE : { } break; #endif case DK4WX_AUTOSTART_REACTION_START : { oAsc.StartProcessing(); #if AUTO_EXIT_ONLY_ON_SUCCESS bSuccess = ChangeScreenSize(); oAsc.EndProcessing(bSuccess); #else (void)ChangeScreenSize(); oAsc.EndProcessing(true); #endif } break; case DK4WX_AUTOSTART_REACTION_MORE : { } break; case DK4WX_AUTOSTART_REACTION_EXIT : { bActive = false; Close(); } break; } event.RequestMore(); } $? "- ScreenSizeFrame::OnIdle" event.Skip(); } /* vim: set ai sw=4 ts=4 : */