DlgSelectMode.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. // DlgSelectMode.cpp : implementation file
  13. //
  14. #include "StdH.h"
  15. #ifdef _DEBUG
  16. #undef new
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. // internal routines for displaying test screen
  22. static void DrawGradient( CDrawPort *pDP, COLOR colStart, COLOR colEnd,
  23. PIX pixI0, PIX pixJ0, PIX pixI1, PIX pixJ1)
  24. {
  25. colStart |= CT_OPAQUE;
  26. colEnd |= CT_OPAQUE;
  27. pDP->Fill( pixI0, pixJ0, pixI1-pixI0, pixJ1-pixJ0, colStart, colEnd, colStart, colEnd);
  28. }
  29. static void ShowTestModeScreen( CDrawPort *pDP, CViewPort *pVP)
  30. {
  31. // try to lock draw port
  32. if( !pDP->Lock()) return;
  33. // draw rectangle
  34. PIX dpWidth = pDP->GetWidth();
  35. PIX dpHeight = pDP->GetHeight();
  36. pDP->Fill( C_WHITE | CT_OPAQUE);
  37. pDP->Fill( 2,2, dpWidth-4, dpHeight-4, C_BLACK | CT_OPAQUE);
  38. // draw gradients
  39. DrawGradient( pDP, C_WHITE, C_RED, 1.0f/8*dpWidth, 1.0f/16*dpHeight, 1.0f/2*dpWidth, 2.0f/16*dpHeight);
  40. DrawGradient( pDP, C_RED, C_BLACK, 1.0f/2*dpWidth, 1.0f/16*dpHeight, 7.0f/8*dpWidth, 2.0f/16*dpHeight);
  41. DrawGradient( pDP, C_BLACK, C_GREEN, 1.0f/8*dpWidth, 2.0f/16*dpHeight, 1.0f/2*dpWidth, 3.0f/16*dpHeight);
  42. DrawGradient( pDP, C_GREEN, C_WHITE, 1.0f/2*dpWidth, 2.0f/16*dpHeight, 7.0f/8*dpWidth, 3.0f/16*dpHeight);
  43. DrawGradient( pDP, C_WHITE, C_BLUE, 1.0f/8*dpWidth, 3.0f/16*dpHeight, 1.0f/2*dpWidth, 4.0f/16*dpHeight);
  44. DrawGradient( pDP, C_BLUE, C_BLACK, 1.0f/2*dpWidth, 3.0f/16*dpHeight, 7.0f/8*dpWidth, 4.0f/16*dpHeight);
  45. DrawGradient( pDP, C_BLACK, C_CYAN, 1.0f/8*dpWidth, 4.5f/16*dpHeight, 1.0f/2*dpWidth, 5.5f/16*dpHeight);
  46. DrawGradient( pDP, C_CYAN, C_WHITE, 1.0f/2*dpWidth, 4.5f/16*dpHeight, 7.0f/8*dpWidth, 5.5f/16*dpHeight);
  47. DrawGradient( pDP, C_WHITE, C_MAGENTA, 1.0f/8*dpWidth, 5.5f/16*dpHeight, 1.0f/2*dpWidth, 6.5f/16*dpHeight);
  48. DrawGradient( pDP, C_MAGENTA, C_BLACK, 1.0f/2*dpWidth, 5.5f/16*dpHeight, 7.0f/8*dpWidth, 6.5f/16*dpHeight);
  49. DrawGradient( pDP, C_BLACK, C_YELLOW, 1.0f/8*dpWidth, 6.5f/16*dpHeight, 1.0f/2*dpWidth, 7.5f/16*dpHeight);
  50. DrawGradient( pDP, C_YELLOW, C_WHITE, 1.0f/2*dpWidth, 6.5f/16*dpHeight, 7.0f/8*dpWidth, 7.5f/16*dpHeight);
  51. DrawGradient( pDP, C_WHITE, C_BLACK, 1.0f/8*dpWidth, 8.0f/16*dpHeight, 7.0f/8*dpWidth, 10.0f/16*dpHeight);
  52. // draw rectangles
  53. pDP->Fill( 1.5f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dRED |CT_OPAQUE);
  54. pDP->Fill( 1.5f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_RED |CT_OPAQUE);
  55. pDP->Fill( 1.5f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lRED |CT_OPAQUE);
  56. pDP->Fill( 2.0f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dGREEN |CT_OPAQUE);
  57. pDP->Fill( 2.0f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_GREEN |CT_OPAQUE);
  58. pDP->Fill( 2.0f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lGREEN |CT_OPAQUE);
  59. pDP->Fill( 2.5f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dBLUE |CT_OPAQUE);
  60. pDP->Fill( 2.5f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_BLUE |CT_OPAQUE);
  61. pDP->Fill( 2.5f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lBLUE |CT_OPAQUE);
  62. pDP->Fill( 3.0f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dCYAN |CT_OPAQUE);
  63. pDP->Fill( 3.0f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_CYAN |CT_OPAQUE);
  64. pDP->Fill( 3.0f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lCYAN |CT_OPAQUE);
  65. pDP->Fill( 3.5f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dMAGENTA |CT_OPAQUE);
  66. pDP->Fill( 3.5f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_MAGENTA |CT_OPAQUE);
  67. pDP->Fill( 3.5f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lMAGENTA |CT_OPAQUE);
  68. pDP->Fill( 4.0f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dYELLOW |CT_OPAQUE);
  69. pDP->Fill( 4.0f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_YELLOW |CT_OPAQUE);
  70. pDP->Fill( 4.0f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lYELLOW |CT_OPAQUE);
  71. pDP->Fill( 4.5f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dGRAY |CT_OPAQUE);
  72. pDP->Fill( 4.5f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_GRAY |CT_OPAQUE);
  73. pDP->Fill( 4.5f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lGRAY |CT_OPAQUE);
  74. pDP->Fill( 5.0f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dORANGE |CT_OPAQUE);
  75. pDP->Fill( 5.0f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_ORANGE |CT_OPAQUE);
  76. pDP->Fill( 5.0f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lORANGE |CT_OPAQUE);
  77. pDP->Fill( 5.5f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dBROWN |CT_OPAQUE);
  78. pDP->Fill( 5.5f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_BROWN |CT_OPAQUE);
  79. pDP->Fill( 5.5f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lBROWN |CT_OPAQUE);
  80. pDP->Fill( 6.0f/8*dpWidth, 10.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_dPINK |CT_OPAQUE);
  81. pDP->Fill( 6.0f/8*dpWidth, 11.0f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_PINK |CT_OPAQUE);
  82. pDP->Fill( 6.0f/8*dpWidth, 11.5f/16*dpHeight, 1.0f/16*dpWidth, 0.5f/16*dpHeight, C_lPINK |CT_OPAQUE);
  83. // set font
  84. pDP->SetFont( _pfdDisplayFont);
  85. // create text to display
  86. CTString strTestMessage = "test screen";
  87. // type messages
  88. pDP->PutTextC( strTestMessage, 1.0f/4*dpWidth, 12.5f/16*dpHeight, C_dRED |CT_OPAQUE);
  89. pDP->PutTextC( strTestMessage, 2.0f/4*dpWidth, 12.5f/16*dpHeight, C_RED |CT_OPAQUE);
  90. pDP->PutTextC( strTestMessage, 3.0f/4*dpWidth, 12.5f/16*dpHeight, C_lRED |CT_OPAQUE);
  91. pDP->PutTextC( strTestMessage, 1.0f/4*dpWidth, 13.0f/16*dpHeight, C_dGREEN|CT_OPAQUE);
  92. pDP->PutTextC( strTestMessage, 2.0f/4*dpWidth, 13.0f/16*dpHeight, C_GREEN |CT_OPAQUE);
  93. pDP->PutTextC( strTestMessage, 3.0f/4*dpWidth, 13.0f/16*dpHeight, C_lGREEN|CT_OPAQUE);
  94. pDP->PutTextC( strTestMessage, 1.0f/4*dpWidth, 13.5f/16*dpHeight, C_dBLUE |CT_OPAQUE);
  95. pDP->PutTextC( strTestMessage, 2.0f/4*dpWidth, 13.5f/16*dpHeight, C_BLUE |CT_OPAQUE);
  96. pDP->PutTextC( strTestMessage, 3.0f/4*dpWidth, 13.5f/16*dpHeight, C_lBLUE |CT_OPAQUE);
  97. pDP->PutTextC( strTestMessage, 1.0f/4*dpWidth, 14.0f/16*dpHeight, C_dGRAY |CT_OPAQUE);
  98. pDP->PutTextC( strTestMessage, 2.0f/4*dpWidth, 14.0f/16*dpHeight, C_GRAY |CT_OPAQUE);
  99. pDP->PutTextC( strTestMessage, 3.0f/4*dpWidth, 14.0f/16*dpHeight, C_lGRAY |CT_OPAQUE);
  100. // type resolution
  101. CDisplayMode dmCurrent;
  102. _pGfx->GetCurrentDisplayMode( dmCurrent);
  103. strTestMessage.PrintF( "%d x %d x %s", dpWidth, dpHeight, dmCurrent.DepthString());
  104. pDP->PutTextC( strTestMessage, 1.0f/2*dpWidth+2, 1.0f/2*dpHeight+2, C_dGRAY|CT_OPAQUE);
  105. pDP->PutTextC( strTestMessage, 1.0f/2*dpWidth, 1.0f/2*dpHeight, C_WHITE|CT_OPAQUE);
  106. // unlock draw port
  107. pDP->Unlock();
  108. // show screen
  109. pVP->SwapBuffers();
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. // CDlgSelectMode dialog
  113. CDlgSelectMode::CDlgSelectMode( CDisplayMode &dm, enum GfxAPIType &gfxAPI,
  114. CWnd* pParent /*=NULL*/) : CDialog( CDlgSelectMode::IDD, pParent)
  115. {
  116. // obtain all available modes
  117. m_pdmAvailableModes = _pGfx->EnumDisplayModes(m_ctAvailableDisplayModes);
  118. // remember initial mode reference
  119. m_pdm = &dm;
  120. m_pGfxAPI = &gfxAPI;
  121. //{{AFX_DATA_INIT(CDlgSelectMode)
  122. m_strCurrentMode = _T("");
  123. m_strCurrentDriver = _T("");
  124. m_iColor = -1;
  125. //}}AFX_DATA_INIT
  126. // set current mode and driver strings
  127. CTString str;
  128. str.PrintF( "%d x %d x %s", dm.dm_pixSizeI, dm.dm_pixSizeJ, dm.DepthString());
  129. m_strCurrentMode = str;
  130. switch(gfxAPI) {
  131. case GAT_OGL:
  132. m_strCurrentDriver = "OpenGL";
  133. break;
  134. #ifdef SE1_D3D
  135. case GAT_D3D:
  136. m_strCurrentDriver = "Direct3D";
  137. break;
  138. #endif // SE1_D3D
  139. default:
  140. m_strCurrentDriver = "none";
  141. break;
  142. }
  143. }
  144. CDlgSelectMode::~CDlgSelectMode()
  145. {
  146. }
  147. void CDlgSelectMode::ApplySettings( CDisplayMode *pdm, enum GfxAPIType *m_pGfxAPI)
  148. {
  149. // pass driver type var
  150. *m_pGfxAPI = (GfxAPIType)m_ctrlDriverCombo.GetCurSel();
  151. // determine color mode
  152. DisplayDepth ddDepth;
  153. switch( m_iColor) {
  154. case 0: ddDepth = DD_DEFAULT; break;
  155. case 1: ddDepth = DD_16BIT; break;
  156. case 2: ddDepth = DD_32BIT; break;
  157. default: ASSERT(FALSE); ddDepth = DD_DEFAULT; break;
  158. }
  159. // get resolution
  160. const ULONG ulRes = (ULONG)m_ctrlResCombo.GetItemData( m_ctrlResCombo.GetCurSel());
  161. const PIX pixSizeI = ulRes>>16;
  162. const PIX pixSizeJ = ulRes&0xFFFF;
  163. // find potentional corresponding modes
  164. for( INDEX iMode=0; iMode<m_ctAvailableDisplayModes; iMode++)
  165. { // if found mode that matches in resolution
  166. if( pixSizeI==m_pdmAvailableModes[iMode].dm_pixSizeI
  167. && pixSizeJ==m_pdmAvailableModes[iMode].dm_pixSizeJ) {
  168. // get it and set wanted depth
  169. pdm->dm_pixSizeI = pixSizeI;
  170. pdm->dm_pixSizeJ = pixSizeJ;
  171. pdm->dm_ddDepth = ddDepth;
  172. }
  173. }
  174. }
  175. void CDlgSelectMode::DoDataExchange(CDataExchange* pDX)
  176. {
  177. CDialog::DoDataExchange(pDX);
  178. // prepare radio buttons
  179. if( !pDX->m_bSaveAndValidate)
  180. {
  181. // set current color radios
  182. switch (m_pdm->dm_ddDepth) {
  183. case DD_DEFAULT: m_iColor = 0; break;
  184. case DD_16BIT : m_iColor = 1; break;
  185. case DD_32BIT : m_iColor = 2; break;
  186. default: ASSERT(FALSE); m_iColor=0; break;
  187. }
  188. }
  189. //{{AFX_DATA_MAP(CDlgSelectMode)
  190. DDX_Control(pDX, IDC_RESOLUTIONS, m_ctrlResCombo);
  191. DDX_Control(pDX, IDC_API, m_ctrlDriverCombo);
  192. DDX_Text(pDX, IDC_CURRENT_MODE, m_strCurrentMode);
  193. DDX_Text(pDX, IDC_CURRENT_DRIVER, m_strCurrentDriver);
  194. DDX_Radio(pDX, IDC_COLOR_DEFAULT, m_iColor);
  195. //}}AFX_DATA_MAP
  196. // if dialog is recieving data
  197. if( !pDX->m_bSaveAndValidate)
  198. {
  199. INDEX i, iSelect=0;
  200. // clear combo boxes
  201. m_ctrlDriverCombo.ResetContent();
  202. m_ctrlResCombo.ResetContent();
  203. // init driver combo
  204. i = m_ctrlDriverCombo.AddString( L"OpenGL");
  205. m_ctrlDriverCombo.SetItemData( i, (INDEX)GAT_OGL);
  206. if( *m_pGfxAPI==GAT_OGL) iSelect = i;
  207. #ifdef SE1_D3D
  208. i = m_ctrlDriverCombo.AddString( L"Direct3D");
  209. m_ctrlDriverCombo.SetItemData( i, (INDEX)GAT_D3D);
  210. if( *m_pGfxAPI==GAT_D3D) iSelect = i;
  211. #endif // SE1_D3D
  212. // set old driver to be default
  213. m_ctrlDriverCombo.SetCurSel( iSelect);
  214. // init resolutions combo
  215. iSelect=0;
  216. for( INDEX iMode=0; iMode<m_ctAvailableDisplayModes; iMode++)
  217. { // prepare resolution string
  218. CTString strRes;
  219. PIX pixSizeI = m_pdmAvailableModes[iMode].dm_pixSizeI;
  220. PIX pixSizeJ = m_pdmAvailableModes[iMode].dm_pixSizeJ;
  221. strRes.PrintF( "%d x %d", pixSizeI, pixSizeJ);
  222. // if not yet added
  223. if( m_ctrlResCombo.FindStringExact( 0, CString(strRes)) == CB_ERR) {
  224. // add it to combo box list
  225. i = m_ctrlResCombo.AddString(CString(strRes));
  226. // set item data to match the resolutions (I in upper word, J in lower)
  227. m_ctrlResCombo.SetItemData( i, (pixSizeI<<16)|pixSizeJ);
  228. // if found old full screen mode
  229. if( pixSizeI==m_pdm->dm_pixSizeI && pixSizeJ==m_pdm->dm_pixSizeJ) {
  230. // mark it to be selected by default
  231. iSelect = i;
  232. }
  233. }
  234. } // set current res combo default mode
  235. m_ctrlResCombo.SetCurSel( iSelect);
  236. }
  237. // --------------------------
  238. // if dialog is giving data
  239. if( pDX->m_bSaveAndValidate)
  240. { // apply new display mode settings
  241. ApplySettings( m_pdm, m_pGfxAPI);
  242. }
  243. }
  244. BEGIN_MESSAGE_MAP(CDlgSelectMode, CDialog)
  245. //{{AFX_MSG_MAP(CDlgSelectMode)
  246. ON_BN_CLICKED(ID_TEST_BUTTON, OnTestButton)
  247. //}}AFX_MSG_MAP
  248. END_MESSAGE_MAP()
  249. /////////////////////////////////////////////////////////////////////////////
  250. // CDlgSelectMode message handlers
  251. void CDlgSelectMode::OnTestButton()
  252. {
  253. CWnd wndTestWindowedMode;
  254. UpdateData( TRUE);
  255. // apply wanted display mode settings
  256. CDisplayMode dm;
  257. enum GfxAPIType gfxAPI;
  258. ApplySettings( &dm, &gfxAPI);
  259. // try to set wanted display mode
  260. PIX pixSizeI = dm.dm_pixSizeI;
  261. PIX pixSizeJ = dm.dm_pixSizeJ;
  262. BOOL bDisplayModeSet = _pGfx->SetDisplayMode( GAT_OGL, 0, pixSizeI, pixSizeJ, dm.dm_ddDepth);
  263. if( !bDisplayModeSet) {
  264. AfxMessageBox( L"Unable to setup full screen display. Test mode failed.");
  265. return;
  266. }
  267. //--------------------------- Open window for testing windowed display mode
  268. // draw ports and viewports needed for printing message
  269. CDrawPort *pDrawPort;
  270. CViewPort *pViewPort;
  271. // get the windows dimensions for this display
  272. int iScreenX = ::GetSystemMetrics(SM_CXSCREEN); // screen size
  273. int iScreenY = ::GetSystemMetrics(SM_CYSCREEN);
  274. // open window of display mode size
  275. const wchar_t *strWindowClass = AfxRegisterWndClass( CS_OWNDC|CS_NOCLOSE);
  276. wndTestWindowedMode.CreateEx( WS_EX_TOPMOST, strWindowClass, L"Test mode",
  277. WS_POPUP|WS_VISIBLE, 0,0, iScreenX,iScreenY, m_hWnd, 0);
  278. // create window canvas
  279. _pGfx->CreateWindowCanvas( wndTestWindowedMode.m_hWnd, &pViewPort, &pDrawPort);
  280. // if screen or window opening was not successful
  281. if( pViewPort == NULL) {
  282. AfxMessageBox( L"Unable to setup full screen display. Test mode failed.");
  283. return;
  284. }
  285. // show test mode screen
  286. ShowTestModeScreen( pDrawPort, pViewPort);
  287. // get starting time
  288. CTimerValue tvStart = _pTimer->GetHighPrecisionTimer();
  289. // loop forever
  290. FOREVER {
  291. // get current time
  292. CTimerValue tvCurrent = _pTimer->GetHighPrecisionTimer();
  293. // get time difference in seconds
  294. CTimerValue tvElapsed = tvCurrent - tvStart;
  295. // three seconds passed?
  296. if( tvElapsed.GetSeconds() > 5.0f) break;
  297. }
  298. // destroy windowed canvas
  299. _pGfx->DestroyWindowCanvas( pViewPort);
  300. pViewPort = NULL;
  301. // destroy window
  302. wndTestWindowedMode.DestroyWindow();
  303. // restore old mode
  304. _pGfx->ResetDisplayMode();
  305. if( AfxMessageBox( L"Did You see displayed message correctly?", MB_YESNO) == IDYES) {
  306. GetDlgItem( IDOK)->SetFocus(); // set focus to apply button
  307. } else {
  308. AfxMessageBox( L"Mode is not valid and it is rejected. Choose another one.");
  309. }
  310. Invalidate( FALSE);
  311. }