1
0

config.cpp 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589
  1. /*
  2. LICENSE
  3. -------
  4. Copyright 2005-2013 Nullsoft, Inc.
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice,
  9. this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice,
  11. this list of conditions and the following disclaimer in the documentation
  12. and/or other materials provided with the distribution.
  13. * Neither the name of Nullsoft nor the names of its contributors may be used to
  14. endorse or promote products derived from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  16. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  21. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  22. OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #include "api__vis_milk2.h"
  25. #include "pluginshell.h"
  26. #include "resource.h"
  27. #include "utility.h"
  28. #include "defines.h"
  29. #include "shell_defines.h"
  30. #include "vis.h"
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <math.h>
  34. #include <multimon.h>
  35. #include <commctrl.h>
  36. #include <shellapi.h>
  37. #include <strsafe.h>
  38. #include <assert.h>
  39. #define PREFERRED_FORMAT D3DFMT_X8R8G8B8
  40. #define MAX_PROPERTY_PAGES 8
  41. #define MAX_DISPLAY_ADAPTERS 16
  42. #define MAX_MAX_FPS 120
  43. #define MAX_DISPLAY_MODES 1024
  44. extern winampVisModule mod1;
  45. IDirect3D9* g_lpDX;
  46. HMODULE g_hmod_d3d9;
  47. HMODULE g_hmod_d3dx9;
  48. D3DADAPTER_IDENTIFIER9 g_disp_adapter_w[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
  49. D3DADAPTER_IDENTIFIER9 g_disp_adapter_fs[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
  50. D3DADAPTER_IDENTIFIER9 g_disp_adapter_dm[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
  51. D3DDISPLAYMODE g_disp_mode[MAX_DISPLAY_MODES];
  52. HWND g_config_hwnd;
  53. HWND g_subwnd;
  54. int g_num_disp_modes;
  55. int g_nTab;
  56. int g_ignore_clicks;
  57. int g_zero_display_modes_warning_given;
  58. int g_proppage_id[MAX_PROPERTY_PAGES];
  59. void GetCurrentDisplayMode(D3DDISPLAYMODE *pMode)
  60. {
  61. if (!pMode)
  62. return;
  63. DEVMODE dm;
  64. dm.dmSize = sizeof(dm);
  65. dm.dmDriverExtra = 0;
  66. if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
  67. return;
  68. pMode->Width = dm.dmPelsWidth;
  69. pMode->Height = dm.dmPelsHeight;
  70. pMode->Format = (dm.dmBitsPerPel==16) ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
  71. pMode->RefreshRate = dm.dmDisplayFrequency;
  72. }
  73. bool CPluginShell::InitConfig(HWND hDialogWnd)
  74. {
  75. // ******* do initialization of global variables HERE *******
  76. // ******* do initialization of global variables HERE *******
  77. // ******* do initialization of global variables HERE *******
  78. g_lpDX = NULL;
  79. g_hmod_d3d9 = NULL;
  80. g_hmod_d3dx9 = NULL;
  81. g_num_disp_modes = 0;
  82. g_config_hwnd = hDialogWnd;
  83. g_ignore_clicks = 1;
  84. g_subwnd = NULL;
  85. g_nTab = 0;
  86. g_zero_display_modes_warning_given = 0;
  87. g_proppage_id[0] = IDD_PROPPAGE_1;
  88. g_proppage_id[1] = IDD_PROPPAGE_2;
  89. g_proppage_id[2] = IDD_PROPPAGE_3;
  90. g_proppage_id[3] = IDD_PROPPAGE_4;
  91. g_proppage_id[4] = IDD_PROPPAGE_5;
  92. g_proppage_id[5] = IDD_PROPPAGE_6;
  93. g_proppage_id[6] = IDD_PROPPAGE_7;
  94. g_proppage_id[7] = IDD_PROPPAGE_8;
  95. // ******* do initialization of global variables HERE *******
  96. // ******* do initialization of global variables HERE *******
  97. // ******* do initialization of global variables HERE *******
  98. return true;
  99. }
  100. void CPluginShell::EndConfig()
  101. {
  102. SafeRelease(g_lpDX);
  103. if (g_subwnd)
  104. {
  105. DestroyWindow(g_subwnd);
  106. g_subwnd = NULL;
  107. }
  108. if (g_hmod_d3d9)
  109. {
  110. FreeLibrary(g_hmod_d3d9);
  111. g_hmod_d3d9 = NULL;
  112. }
  113. if (g_hmod_d3dx9)
  114. {
  115. g_hmod_d3dx9 = NULL;
  116. }
  117. }
  118. static bool AddButton(int pos, HWND tabctrl, LPWSTR szButtonText)
  119. {
  120. if (szButtonText && szButtonText[0] && szButtonText[0] != L' ')
  121. {
  122. TCITEMW tie = {0};
  123. tie.mask = TCIF_TEXT | TCIF_IMAGE;
  124. tie.iImage = -1;
  125. tie.pszText = szButtonText;
  126. if (SendMessageW(tabctrl, TCM_INSERTITEMW, pos, (LPARAM)&tie) == -1)
  127. return false;
  128. }
  129. return true;
  130. }
  131. void CPluginShell::UpdateAdapters(int screenmode)
  132. {
  133. int i;
  134. if (!g_lpDX) return;
  135. int nDispAdapters = 0;
  136. HWND ctrl;
  137. GUID* pGUID = NULL;
  138. char deviceName[256];
  139. switch(screenmode)
  140. {
  141. case FULLSCREEN:
  142. ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS);
  143. pGUID = &m_adapter_guid_fullscreen;
  144. StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_fullscreen);
  145. break;
  146. case WINDOWED:
  147. ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W);
  148. pGUID = &m_adapter_guid_windowed;
  149. StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_windowed);
  150. break;
  151. /*case FAKE_FULLSCREEN:
  152. ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS);
  153. pGUID = &m_adapter_guid_fake_fullscreen;
  154. strcpy(deviceName, m_adapter_devicename_fake_fullscreen);
  155. break;*/
  156. case DESKTOP:
  157. ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS);
  158. pGUID = &m_adapter_guid_desktop;
  159. StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_desktop);
  160. break;
  161. }
  162. // clear the combo box
  163. SendMessage( ctrl, CB_RESETCONTENT, 0, 0);
  164. // repopulate the combo box with a list of adapters
  165. {
  166. char szDesc[1024];
  167. D3DADAPTER_IDENTIFIER9* global_adapter_list;
  168. switch(screenmode)
  169. {
  170. case FULLSCREEN:
  171. global_adapter_list = g_disp_adapter_fs;
  172. break;
  173. case WINDOWED:
  174. global_adapter_list = g_disp_adapter_w;
  175. break;
  176. /*case FAKE_FULLSCREEN:
  177. global_adapter_list = g_disp_adapter_w; // [sic]
  178. break;*/
  179. case DESKTOP:
  180. global_adapter_list = g_disp_adapter_dm;
  181. break;
  182. }
  183. int nAdapters = g_lpDX->GetAdapterCount();
  184. // re-populate it:
  185. wchar_t szDebugFile[MAX_PATH];
  186. StringCbCopyW(szDebugFile, sizeof(szDebugFile), m_szConfigIniFile);
  187. wchar_t* p = wcsrchr(szDebugFile, L'\\');
  188. if (p)
  189. {
  190. lstrcpyW(p+1, ADAPTERSFILE);
  191. FILE* f = _wfopen(szDebugFile, L"w");
  192. if (f)
  193. {
  194. DWORD winamp_version = SendMessage(GetWinampWindow(),WM_WA_IPC,0,0);
  195. fprintf(f, "Winamp version = 0x%04X\n", winamp_version);
  196. fprintf(f, "Plugin long name = \"%s\", version=%d, subversion=%d\n", LONGNAME, INT_VERSION, INT_SUBVERSION);
  197. fprintf(f, "Enumeration of Display Adapters:\n");
  198. //fprintf(f, "...this is a temporary debug file created by MilkDrop 2.\n");
  199. //fprintf(f, "...don't worry - the final release of the plug-in will NOT generate this file.\n");
  200. for (i=0; i<nAdapters && nDispAdapters<MAX_DISPLAY_ADAPTERS; i++)
  201. {
  202. if (g_lpDX->GetAdapterIdentifier(i, /*D3DENUM_NO_WHQL_LEVEL*/ 0, &global_adapter_list[nDispAdapters]) == D3D_OK)
  203. {
  204. // Now get the caps, and filter out any graphics cards that can't
  205. // do, say, gouraud shading:
  206. int adapter_ok = 1;
  207. /*
  208. D3DCAPS9 caps;
  209. if (g_lpDX->GetDeviceCaps(i, D3DDEVTYPE_HAL, &caps)==D3D_OK)
  210. {
  211. // check the caps here, make sure the device is up to par. example:
  212. if (caps.ShadeCaps & D3DPSHADECAPS_COLORGOURAUDRGB)
  213. adapter_ok = 0;
  214. }
  215. */
  216. if (f) {
  217. fprintf(f, "%d. Driver=%s\n", nDispAdapters+1, global_adapter_list[nDispAdapters].Driver);
  218. fprintf(f, " Description=%s\n", global_adapter_list[nDispAdapters].Description);
  219. fprintf(f, " DeviceName=%s\n", global_adapter_list[nDispAdapters].DeviceName);
  220. fprintf(f, " DriverVersion=0x%08X (%d)\n",global_adapter_list[nDispAdapters].DriverVersion);
  221. fprintf(f, " VendorId=%d\n", global_adapter_list[nDispAdapters].VendorId);
  222. fprintf(f, " DeviceId=%d\n", global_adapter_list[nDispAdapters].DeviceId);
  223. fprintf(f, " SubSysId=0x%08X\n", global_adapter_list[nDispAdapters].SubSysId);
  224. fprintf(f, " Revision=%d\n", global_adapter_list[nDispAdapters].Revision);
  225. //fprintf(f, " DeviceIdentifier=0x%08X\n", global_adapter_list[nDispAdapters].DeviceIdentifier);
  226. char szGuidText[512];
  227. GuidToText(&global_adapter_list[nDispAdapters].DeviceIdentifier, szGuidText, sizeof(szGuidText));
  228. fprintf(f, " WHQLLevel=%d\n", global_adapter_list[nDispAdapters].WHQLLevel);
  229. fprintf(f, " GUID=%s\n", szGuidText);
  230. }
  231. if (adapter_ok)
  232. {
  233. sprintf(szDesc, "%d. %s [%s]", nDispAdapters+1, global_adapter_list[nDispAdapters].Description, global_adapter_list[nDispAdapters].Driver);
  234. SendMessage( ctrl, CB_ADDSTRING, nDispAdapters, (LPARAM)szDesc);
  235. nDispAdapters++;
  236. }
  237. }
  238. }
  239. fclose(f);
  240. }
  241. }
  242. // set selection(s):
  243. // find i where global_adapter_list[i].DeviceIdentifier is the same as last time,
  244. // and select it.
  245. int found = 0;
  246. for (i=0; i<nDispAdapters; i++)
  247. {
  248. if (!found &&
  249. memcmp(&global_adapter_list[i].DeviceIdentifier, pGUID, sizeof(GUID))==0 &&
  250. !strcmp(global_adapter_list[i].DeviceName, deviceName)
  251. )
  252. {
  253. SendMessage( ctrl, CB_SETCURSEL, i, 0);
  254. found = 1;
  255. }
  256. }
  257. if (!found)
  258. SendMessage( ctrl, CB_SETCURSEL, 0, 0);
  259. }
  260. if (screenmode == FULLSCREEN)
  261. UpdateFSAdapterDispModes();
  262. else
  263. UpdateDispModeMultiSampling(screenmode);
  264. }
  265. void CPluginShell::UpdateFSAdapterDispModes() // (fullscreen only)
  266. {
  267. wchar_t szfmt[256], str[256];
  268. int i;
  269. HWND hwnd_listbox = GetDlgItem( g_subwnd, IDC_DISP_MODE );
  270. int nVideoModesTotal = 0;
  271. if (!g_lpDX) return;
  272. int nAdapterOrdinal = GetCurrentlySelectedAdapter(FULLSCREEN);
  273. nVideoModesTotal = g_lpDX->GetAdapterModeCount(nAdapterOrdinal, PREFERRED_FORMAT);
  274. if (nVideoModesTotal <= 0 && !g_zero_display_modes_warning_given)
  275. {
  276. g_zero_display_modes_warning_given = 1;
  277. wchar_t title[64];
  278. MessageBoxW(g_config_hwnd, WASABI_API_LNGSTRINGW(IDS_GRAPHICS_SUBSYSTEM_IS_TEMPORARILY_UNSTABLE),
  279. WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING, title, 64),
  280. MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  281. }
  282. // clear the combo box
  283. SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
  284. int nAdded = 0;
  285. // re-populate it:
  286. for (i=0; i<nVideoModesTotal; i++)
  287. {
  288. if (nAdded >= MAX_DISPLAY_MODES)
  289. break;
  290. // get info for display mode into g_disp_mode[nAdded]
  291. if (g_lpDX->EnumAdapterModes(nAdapterOrdinal, PREFERRED_FORMAT, i, &g_disp_mode[nAdded]) != D3D_OK)
  292. continue;
  293. // add to combo box
  294. int bpp = 0;
  295. switch(g_disp_mode[nAdded].Format)
  296. {
  297. default:
  298. case D3DFMT_UNKNOWN : WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN, szfmt, 256); bpp=0; break;
  299. case D3DFMT_R8G8B8 : lstrcpynW(szfmt, L"RGB-888", 256); bpp=32; break;
  300. case D3DFMT_A8R8G8B8 : lstrcpynW(szfmt, L"ARGB-8888", 256); bpp=32; break;
  301. case D3DFMT_X8R8G8B8 : lstrcpynW(szfmt, L"XRGB-8888", 256); bpp=32; break;
  302. case D3DFMT_R5G6B5 : lstrcpynW(szfmt, L"RGB-565", 256); bpp=16; break;
  303. case D3DFMT_X1R5G5B5 : lstrcpynW(szfmt, L"XRGB-1555", 256); bpp=16; break;
  304. case D3DFMT_A1R5G5B5 : lstrcpynW(szfmt, L"ARGB-1555", 256); bpp=16; break;
  305. case D3DFMT_A4R4G4B4 : lstrcpynW(szfmt, L"ARGB-4444", 256); bpp=16; break;
  306. case D3DFMT_X4R4G4B4 : lstrcpynW(szfmt, L"XRGB-4444", 256); bpp=16; break;
  307. }
  308. swprintf(str, L" %s, %4d x %4d, %3d %s ",
  309. szfmt, g_disp_mode[nAdded].Width,
  310. g_disp_mode[nAdded].Height,
  311. g_disp_mode[nAdded].RefreshRate,
  312. WASABI_API_LNGSTRINGW(IDS_HZ));
  313. /*
  314. #ifdef DONT_ALLOW_8BIT_FULLSCREEN
  315. if (bpp==8) continue;
  316. #endif
  317. #ifdef DONT_ALLOW_16_24_32_BIT_FULLSCREEN
  318. if (bpp==16 || bpp==24 || bpp==32) continue;
  319. #endif
  320. */
  321. int nPos = SendMessageW( hwnd_listbox, CB_ADDSTRING, 0, (LPARAM)str);
  322. // keep a record of the original index, because the combo box SORTS the data:
  323. SendMessage( hwnd_listbox, CB_SETITEMDATA, nPos, i);
  324. nAdded++;
  325. }
  326. g_num_disp_modes = nAdded;
  327. // now set selection, based on best match to prev. video mode.
  328. int found = 0;
  329. // Fallback order:
  330. // 0. exact match (4 params) w,h,r,f
  331. // 1. ignore refresh rate, but still heed color format
  332. // 2. heed only w,h, and if desired_mode.Format is UNKNOWN,
  333. // try for a 16-bpp color format and 60 Hz
  334. // 3. heed only w,h, and if desired_mode.Format is UNKNOWN,
  335. // try for a 16-bpp color format at any Hz
  336. // 4. heed only w,h.
  337. D3DDISPLAYMODE desired_mode = m_disp_mode_fs;
  338. assert(desired_mode.Format != D3DFMT_UNKNOWN);
  339. // this should never happen anymore, now that we set smarter default FS display mode
  340. // (to match the current display mode) in PluginShell.cpp's PluginPreInitialize().
  341. /*if (desired_mode.Format==D3DFMT_UNKNOWN)
  342. {
  343. GetCurrentDisplayMode(&desired_mode);
  344. // first-time config: try to find a video mode that matches our ideal.
  345. // do many passes until we find one, each time relaxing more constraints.
  346. // outline of the passes:
  347. // PASS MATCH:
  348. // 0. w,h,r,16bpp
  349. // 1. w,h,-,16bpp
  350. // 2. w,h,r,-
  351. // 3. w,h,-,-
  352. // 4. -,-,-,-
  353. for (int rep=0; rep<5; rep++)
  354. {
  355. for (i=0; i<g_num_disp_modes && !found; i++)
  356. {
  357. // we have to remap here, because the combo box SORTED the data:
  358. int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
  359. bool bDesiredBitDepth = (
  360. (g_disp_mode[id].Format == D3DFMT_R8G8B8 ) ||
  361. (g_disp_mode[id].Format == D3DFMT_A8R8G8B8) ||
  362. (g_disp_mode[id].Format == D3DFMT_X8R8G8B8)
  363. );
  364. bool bMatch = true;
  365. if (rep<=3 && desired_mode.Width!=g_disp_mode[id].Width)
  366. bMatch = false;
  367. if (rep<=3 && desired_mode.Height!=g_disp_mode[id].Height)
  368. bMatch = false;
  369. if ((rep==0 || rep==2) && desired_mode.RefreshRate!=g_disp_mode[id].RefreshRate)
  370. bMatch = false;
  371. if (rep<=1 && !bDesiredBitDepth)
  372. bMatch = false;
  373. if (bMatch)
  374. {
  375. SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
  376. found = 1;
  377. }
  378. }
  379. }
  380. // if no match could be found, select #0.
  381. if (!found)
  382. SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
  383. }
  384. else
  385. */
  386. {
  387. // find best match to prev. selection.
  388. // do many passes until we find one, each time relaxing more constraints.
  389. // outline of the passes:
  390. int bpp_desired = 0;
  391. switch(desired_mode.Format)
  392. {
  393. case D3DFMT_R8G8B8 : bpp_desired = 32; break;
  394. case D3DFMT_A8R8G8B8: bpp_desired = 32; break;
  395. case D3DFMT_X8R8G8B8: bpp_desired = 32; break;
  396. case D3DFMT_R5G6B5 : bpp_desired = 16; break;
  397. case D3DFMT_X1R5G5B5: bpp_desired = 16; break;
  398. case D3DFMT_A1R5G5B5: bpp_desired = 16; break;
  399. case D3DFMT_A4R4G4B4: bpp_desired = 16; break;
  400. case D3DFMT_R3G3B2 : bpp_desired = 8; break;
  401. case D3DFMT_A8R3G3B2: bpp_desired = 16; break;
  402. case D3DFMT_X4R4G4B4: bpp_desired = 16; break;
  403. }
  404. // rep MATCH:
  405. // 0. w,h,r,f
  406. // 1. w,h,-,f
  407. // 2. w,h,r,- pass:
  408. // 3. w,h,-,- -on pass 0, for 'f', match exact format
  409. // 4. 8,6,r,f -on pass 1, for 'f', just match # of bits per pixel
  410. // 5. 8,6,-,f (more relaxed match)
  411. // 6. 8,6,r,-
  412. // 7. 8,6,-,-
  413. // 8. -,-,r,f
  414. // 9. -,-,-,f
  415. // 10. -,-,r,-
  416. // 11. -,-,-,-
  417. for (int rep=0; rep<12 && !found; rep++)
  418. {
  419. for (int pass=0; pass<2 && !found; pass++)
  420. {
  421. for (i=0; i<g_num_disp_modes && !found; i++)
  422. {
  423. // we have to remap here, because the combo box SORTED the data:
  424. int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
  425. int bpp_this_mode = 0;
  426. switch(g_disp_mode[id].Format)
  427. {
  428. case D3DFMT_R8G8B8 : bpp_this_mode = 32; break;
  429. case D3DFMT_A8R8G8B8: bpp_this_mode = 32; break;
  430. case D3DFMT_X8R8G8B8: bpp_this_mode = 32; break;
  431. case D3DFMT_R5G6B5 : bpp_this_mode = 16; break;
  432. case D3DFMT_X1R5G5B5: bpp_this_mode = 16; break;
  433. case D3DFMT_A1R5G5B5: bpp_this_mode = 16; break;
  434. case D3DFMT_A4R4G4B4: bpp_this_mode = 16; break;
  435. case D3DFMT_R3G3B2 : bpp_this_mode = 8; break;
  436. case D3DFMT_A8R3G3B2: bpp_this_mode = 16; break;
  437. case D3DFMT_X4R4G4B4: bpp_this_mode = 16; break;
  438. }
  439. bool bMatch = true;
  440. if (rep < 4)
  441. {
  442. if (desired_mode.Width != g_disp_mode[id].Width)
  443. bMatch = false;
  444. if (desired_mode.Height != g_disp_mode[id].Height)
  445. bMatch = false;
  446. }
  447. else if (rep < 8)
  448. {
  449. if (DEFAULT_FULLSCREEN_WIDTH != g_disp_mode[id].Width)
  450. bMatch = false;
  451. if (DEFAULT_FULLSCREEN_HEIGHT != g_disp_mode[id].Height)
  452. bMatch = false;
  453. }
  454. if (((rep/2)%2)==0)
  455. {
  456. if (pass==0 && desired_mode.Format != g_disp_mode[id].Format)
  457. bMatch = false;
  458. else if (pass==1 && bpp_desired != bpp_this_mode)
  459. bMatch = false;
  460. }
  461. if (((rep%2)==0) && desired_mode.RefreshRate!=g_disp_mode[id].RefreshRate)
  462. {
  463. bMatch = false;
  464. }
  465. if (bMatch)
  466. {
  467. SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
  468. found = 1;
  469. }
  470. }
  471. }
  472. }
  473. // if no match could be found, select #0.
  474. if (!found)
  475. SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
  476. }
  477. UpdateDispModeMultiSampling(0);
  478. }
  479. void CPluginShell::UpdateDispModeMultiSampling(int screenmode)
  480. {
  481. int nSampleTypes = 0;
  482. HWND hwnd_listbox;
  483. switch(screenmode)
  484. {
  485. case FULLSCREEN: hwnd_listbox = GetDlgItem(g_subwnd, IDC_FSMS); break;
  486. case WINDOWED: hwnd_listbox = GetDlgItem(g_subwnd, IDC_WMS); break;
  487. case DESKTOP: hwnd_listbox = GetDlgItem(g_subwnd, IDC_DMSMS); break;
  488. }
  489. wchar_t str[256];
  490. int i;
  491. if (!g_lpDX)
  492. return;
  493. if ((screenmode == WINDOWED && !m_allow_page_tearing_w) ||
  494. (screenmode == FULLSCREEN && m_fake_fullscreen_mode && !m_allow_page_tearing_fs) ||
  495. (screenmode == DESKTOP && !m_allow_page_tearing_dm))
  496. {
  497. // page tearing not allowed -> disable multisampling!
  498. SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
  499. SendMessageW( hwnd_listbox, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_DISABLED_PAGE_TEARING));
  500. SendMessage( hwnd_listbox, CB_SETITEMDATA, 0, 0 );
  501. SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
  502. EnableWindow( hwnd_listbox, 0 );
  503. }
  504. else
  505. {
  506. EnableWindow( hwnd_listbox, 1 );
  507. // figure out which [fullscreen/windowed] adapter is currently selected:
  508. int nAdapterOrdinal = GetCurrentlySelectedAdapter(screenmode);
  509. // figure out current format:
  510. D3DFORMAT format = D3DFMT_UNKNOWN;
  511. if ((screenmode == WINDOWED) ||
  512. (screenmode == FULLSCREEN && m_fake_fullscreen_mode) ||
  513. (screenmode == DESKTOP))
  514. {
  515. // ** get it from the current display mode
  516. // of the currently-selected [windowed/fake fullscreen] mode adapter **
  517. D3DDISPLAYMODE dispmode;
  518. if (g_lpDX->GetAdapterDisplayMode(nAdapterOrdinal, &dispmode) == D3D_OK)
  519. format = dispmode.Format;
  520. }
  521. else
  522. {
  523. // **get it from the currently-selected fullscreen display mode**
  524. int n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETCURSEL, 0, 0);
  525. if (n != CB_ERR)
  526. {
  527. // since the combobox contents were sorted, we need to look up the original
  528. // index into g_disp_mode[]:
  529. n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETITEMDATA, n, 0);
  530. if (n != CB_ERR)
  531. format = g_disp_mode[n].Format;
  532. }
  533. }
  534. D3DMULTISAMPLE_TYPE check[16] = {
  535. D3DMULTISAMPLE_NONE,
  536. D3DMULTISAMPLE_2_SAMPLES ,
  537. D3DMULTISAMPLE_3_SAMPLES ,
  538. D3DMULTISAMPLE_4_SAMPLES ,
  539. D3DMULTISAMPLE_5_SAMPLES ,
  540. D3DMULTISAMPLE_6_SAMPLES ,
  541. D3DMULTISAMPLE_7_SAMPLES ,
  542. D3DMULTISAMPLE_8_SAMPLES ,
  543. D3DMULTISAMPLE_9_SAMPLES ,
  544. D3DMULTISAMPLE_10_SAMPLES,
  545. D3DMULTISAMPLE_11_SAMPLES,
  546. D3DMULTISAMPLE_12_SAMPLES,
  547. D3DMULTISAMPLE_13_SAMPLES,
  548. D3DMULTISAMPLE_14_SAMPLES,
  549. D3DMULTISAMPLE_15_SAMPLES,
  550. D3DMULTISAMPLE_16_SAMPLES,
  551. };
  552. // clear the combo box
  553. SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
  554. // re-populate it:
  555. for (i=0; i<16; i++)
  556. {
  557. if (i==0 || SUCCEEDED(g_lpDX->CheckDeviceMultiSampleType(nAdapterOrdinal, D3DDEVTYPE_HAL,
  558. format,
  559. (screenmode==FULLSCREEN) ? 0 : 1,//bWindowed,
  560. check[i], NULL)))
  561. {
  562. // add to listbox
  563. if (i==0)
  564. WASABI_API_LNGSTRINGW_BUF(IDS_NONE, str, 256);
  565. else
  566. StringCbPrintfW(str, sizeof(str), L"%2dX", i+1);
  567. SendMessage( hwnd_listbox, CB_ADDSTRING, nSampleTypes, (LPARAM)str);
  568. // set the item data to the D3DMULTISAMPLE_TYPE value:
  569. SendMessage( hwnd_listbox, CB_SETITEMDATA, nSampleTypes, check[i] );
  570. nSampleTypes++;
  571. }
  572. }
  573. // set prev. selection
  574. D3DMULTISAMPLE_TYPE prev_seln;
  575. switch(screenmode)
  576. {
  577. case FULLSCREEN: prev_seln = m_multisample_fullscreen; break;
  578. case WINDOWED: prev_seln = m_multisample_windowed; break;
  579. //case FAKE_FULLSCREEN: prev_seln = m_multisample_fake_fullscreen; break;
  580. case DESKTOP: prev_seln = m_multisample_desktop; break;
  581. }
  582. for (i=0; i<nSampleTypes; i++)
  583. {
  584. int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
  585. if (id==prev_seln)
  586. {
  587. SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
  588. return;
  589. }
  590. }
  591. SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
  592. }
  593. }
  594. void CPluginShell::UpdateMaxFps(int screenmode)
  595. {
  596. // initialize sleep combo boxes
  597. HWND ctrl;
  598. switch(screenmode)
  599. {
  600. case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FS_MAXFPS ); break;
  601. case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_W_MAXFPS ); break;
  602. //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFS_MAXFPS); break;
  603. case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMS_MAXFPS); break;
  604. }
  605. SendMessage( ctrl, CB_RESETCONTENT, 0, 0);
  606. for (int j=0; j<=MAX_MAX_FPS; j++)
  607. {
  608. wchar_t buf[256];
  609. if (j==0)
  610. WASABI_API_LNGSTRINGW_BUF(IDS_UNLIMITED, buf, 256);
  611. else
  612. swprintf(buf, WASABI_API_LNGSTRINGW(IDS_X_FRAME_SEC), (j<MAX_MAX_FPS)?(MAX_MAX_FPS+1-j):(MAX_MAX_FPS+1-j));
  613. SendMessageW( ctrl, CB_ADDSTRING, j, (LPARAM)buf);
  614. }
  615. // set prev. selection
  616. int max_fps;
  617. switch(screenmode)
  618. {
  619. case FULLSCREEN: max_fps = m_max_fps_fs; break;
  620. case WINDOWED: max_fps = m_max_fps_w; break;
  621. //case FAKE_FULLSCREEN: max_fps = m_max_fps_fake_fs; break;
  622. case DESKTOP: max_fps = m_max_fps_dm; break;
  623. }
  624. if (max_fps == 0)
  625. SendMessage(ctrl, CB_SETCURSEL, 0, 0);
  626. else
  627. SendMessage(ctrl, CB_SETCURSEL, MAX_MAX_FPS-max_fps+1, 0);
  628. }
  629. int CPluginShell::GetCurrentlySelectedAdapter(int screenmode)
  630. {
  631. // returns the ordinal adapter #.
  632. HWND ctrl;
  633. switch(screenmode)
  634. {
  635. case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS ); break;
  636. case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W ); break;
  637. //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS); break;
  638. case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS); break;
  639. }
  640. int n = SendMessage(ctrl, CB_GETCURSEL, 0, 0);
  641. //if (n != CB_ERR)
  642. // n = SendMessage(ctrl, CB_GETITEMDATA, n, 0);
  643. if (n != CB_ERR)
  644. return n;
  645. else
  646. return D3DADAPTER_DEFAULT;
  647. }
  648. void CPluginShell::SaveDisplayMode()
  649. {
  650. //if (m_fake_fullscreen_mode)
  651. // return;
  652. // read fullscreen display mode
  653. int n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETCURSEL, 0, 0);
  654. if (n != CB_ERR)
  655. {
  656. // since the combobox contents were sorted, we need to look up the original
  657. // index into g_disp_mode[]:
  658. n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETITEMDATA, n, 0);
  659. if (n != CB_ERR)
  660. m_disp_mode_fs = g_disp_mode[n];
  661. }
  662. }
  663. void CPluginShell::SaveMultiSamp(int screenmode)
  664. {
  665. HWND ctrl;
  666. switch(screenmode)
  667. {
  668. case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FSMS); break;
  669. case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_WMS); break;
  670. //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFSMS); break;
  671. case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMSMS); break;
  672. }
  673. // if page tearing is disabled, then multisampling must be disabled,
  674. // so ignore multisample selection
  675. if (g_subwnd && g_nTab==0)
  676. {
  677. if (screenmode == WINDOWED && !m_allow_page_tearing_w)
  678. return;
  679. if (screenmode == DESKTOP && !m_allow_page_tearing_dm)
  680. return;
  681. if (screenmode == FULLSCREEN && m_fake_fullscreen_mode && !m_allow_page_tearing_fs)
  682. return;
  683. }
  684. // read windowed & fullscreen multisampling settings:
  685. int n = SendMessage(ctrl , CB_GETCURSEL, 0, 0);
  686. if (n != CB_ERR)
  687. {
  688. n = SendMessage( ctrl, CB_GETITEMDATA, n, 0);
  689. if (n != CB_ERR)
  690. {
  691. switch(screenmode)
  692. {
  693. case FULLSCREEN: m_multisample_fullscreen = (D3DMULTISAMPLE_TYPE)n; break;
  694. case WINDOWED: m_multisample_windowed = (D3DMULTISAMPLE_TYPE)n; break;
  695. //case FAKE_FULLSCREEN: m_multisample_fake_fullscreen = (D3DMULTISAMPLE_TYPE)n; break;
  696. case DESKTOP: m_multisample_desktop = (D3DMULTISAMPLE_TYPE)n; break;
  697. }
  698. }
  699. }
  700. }
  701. void CPluginShell::SaveMaxFps(int screenmode)
  702. {
  703. HWND ctrl;
  704. switch(screenmode)
  705. {
  706. case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FS_MAXFPS); break;
  707. case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_W_MAXFPS); break;
  708. //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFS_MAXFPS); break;
  709. case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMS_MAXFPS); break;
  710. }
  711. // read max fps settings
  712. int n = SendMessage(ctrl, CB_GETCURSEL, 0, 0);
  713. if (n != CB_ERR)
  714. {
  715. if (n > 0)
  716. n = MAX_MAX_FPS+1 - n;
  717. switch(screenmode)
  718. {
  719. case FULLSCREEN: m_max_fps_fs = n; break;
  720. case WINDOWED: m_max_fps_w = n; break;
  721. //case FAKE_FULLSCREEN: m_max_fps_fake_fs = n; break;
  722. case DESKTOP: m_max_fps_dm = n; break;
  723. }
  724. }
  725. }
  726. void CPluginShell::SaveAdapter(int screenmode)
  727. {
  728. HWND ctrl;
  729. switch(screenmode)
  730. {
  731. case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS); break;
  732. case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W); break;
  733. //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS); break;
  734. case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS); break;
  735. }
  736. // save windowed/fullscreen adapter
  737. int n = SendMessage( ctrl, CB_GETCURSEL, 0, 0);
  738. if (n != CB_ERR)
  739. {
  740. switch(screenmode)
  741. {
  742. case FULLSCREEN:
  743. m_adapter_guid_fullscreen = g_disp_adapter_fs[n].DeviceIdentifier;
  744. StringCbCopy(m_adapter_devicename_fullscreen, sizeof(m_adapter_devicename_fullscreen), g_disp_adapter_fs[n].DeviceName);
  745. //strcpy(m_adapter_desc_fullscreen, g_disp_adapter_fs[n].Description);
  746. break;
  747. case WINDOWED:
  748. m_adapter_guid_windowed = g_disp_adapter_w[n].DeviceIdentifier;
  749. StringCbCopy(m_adapter_devicename_windowed, sizeof(m_adapter_devicename_windowed), g_disp_adapter_fs[n].DeviceName);
  750. //strcpy(m_adapter_desc_windowed, g_disp_adapter_fs[n].Description);
  751. break;
  752. //case FAKE_FULLSCREEN:
  753. //m_adapter_guid_fake_fullscreen = g_disp_adapter_w[n].DeviceIdentifier;
  754. //strcpy(m_adapter_desc_fake_fullscreen, g_disp_adapter_fs[n].Description);
  755. //break; // [sic]
  756. case DESKTOP:
  757. m_adapter_guid_desktop = g_disp_adapter_dm[n].DeviceIdentifier;
  758. StringCbCopy(m_adapter_devicename_desktop, sizeof(m_adapter_devicename_desktop), g_disp_adapter_fs[n].DeviceName);
  759. //strcpy(m_adapter_desc_desktop, g_disp_adapter_fs[n].Description);
  760. break;
  761. }
  762. }
  763. }
  764. /*
  765. BOOL CALLBACK GenericTabCtrlProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  766. {
  767. return 0;
  768. }
  769. */
  770. // OnTabChanged - processes the TCN_SELCHANGE notification.
  771. void CPluginShell::OnTabChanged(int nNewTab)
  772. {
  773. if (g_subwnd)
  774. {
  775. DestroyWindow(g_subwnd);
  776. g_subwnd = NULL;
  777. }
  778. g_nTab = nNewTab;
  779. if (g_nTab >= 0 && g_nTab < MAX_PROPERTY_PAGES)
  780. {
  781. HWND h = WASABI_API_CREATEDIALOGPARAMW(g_proppage_id[g_nTab], g_config_hwnd, this->TabCtrlProc, (LPARAM)this);
  782. // NOTE: CreateDialogParam will call TabCtrlProc with WM_INITDIALOG,
  783. // which is where 'g_subwnd' will get set.
  784. // do this here to ensure that the current prefs page is correctly themed
  785. if(!SendMessage(this->m_hWndWinamp,WM_WA_IPC,IPC_ISWINTHEMEPRESENT,IPC_USE_UXTHEME_FUNC))
  786. {
  787. SendMessage(this->m_hWndWinamp,WM_WA_IPC,(WPARAM)h,IPC_USE_UXTHEME_FUNC);
  788. }
  789. }
  790. }
  791. INT_PTR CALLBACK CPluginShell::TabCtrlProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  792. {
  793. if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
  794. SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
  795. CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
  796. if (p && g_nTab >= 0 && g_nTab < MAX_PROPERTY_PAGES)
  797. {
  798. if (msg==WM_INITDIALOG)
  799. g_subwnd = hwnd;
  800. if (g_nTab==0)
  801. p->PluginShellConfigTab1Proc(hwnd, msg, wParam, lParam);
  802. p->MyConfigTabProc(g_nTab+1, hwnd, msg, wParam, lParam);
  803. if (msg==WM_INITDIALOG)
  804. {
  805. // once it has been initialized, reposition the subdialog:
  806. RECT r;
  807. GetWindowRect(GetDlgItem(g_config_hwnd,IDC_RECT),&r);
  808. ScreenToClient(g_config_hwnd,(LPPOINT)&r);
  809. SetWindowPos(g_subwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  810. ShowWindow(g_subwnd,SW_SHOWNA);
  811. }
  812. }
  813. const int controls[] =
  814. {
  815. IDC_BRIGHT_SLIDER,
  816. IDC_HARDCUT_LOUDNESS,
  817. };
  818. if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwnd, msg, wParam, lParam, controls, ARRAYSIZE(controls)))
  819. {
  820. return TRUE;
  821. }
  822. return FALSE;
  823. }
  824. BOOL CPluginShell::PluginShellConfigTab1Proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  825. {
  826. #ifdef _DEBUG
  827. OutputDebugMessage(" Tab1Proc: ", hwnd, msg, wParam, lParam);
  828. #endif
  829. switch (msg)
  830. {
  831. case WM_INITDIALOG:
  832. {
  833. // pre-checks
  834. if (m_start_fullscreen && m_start_desktop)
  835. m_start_desktop = 0;
  836. if (!mod1.hwndParent || SendMessage(mod1.hwndParent,WM_WA_IPC,0,0) < 0x2900)
  837. {
  838. m_skin = 0;
  839. EnableWindow(GetDlgItem(hwnd,IDC_CB_SKIN), 0);
  840. char buf[256];
  841. buf[0] = 0;
  842. GetWindowText(GetDlgItem(hwnd,IDC_CB_SKIN), buf, 255);
  843. StringCbCat(buf, sizeof(buf), " 2.90+");
  844. SetWindowText(GetDlgItem(hwnd,IDC_CB_SKIN), buf);
  845. }
  846. // set checkboxes
  847. CheckDlgButton(hwnd, IDC_CB_FS, m_start_fullscreen);
  848. CheckDlgButton(hwnd, IDC_CB_DMS, m_start_desktop);
  849. CheckDlgButton(hwnd, IDC_CB_FAKE, m_fake_fullscreen_mode);
  850. CheckDlgButton(hwnd, IDC_CB_PRESS_F1_MSG, m_show_press_f1_msg);
  851. CheckDlgButton(hwnd, IDC_CB_WPT, m_allow_page_tearing_w);
  852. CheckDlgButton(hwnd, IDC_CB_FSPT, m_allow_page_tearing_fs);
  853. CheckDlgButton(hwnd, IDC_CB_DMSPT, m_allow_page_tearing_dm);
  854. CheckDlgButton(hwnd, IDC_CB_MIN, m_minimize_winamp);
  855. CheckDlgButton(hwnd, IDC_CB_SAVE_CPU, m_save_cpu);
  856. CheckDlgButton(hwnd, IDC_CB_SKIN, m_skin);
  857. CheckDlgButton(hwnd, IDC_CB_FIXSLOWTEXT, m_fix_slow_text);
  858. CheckDlgButton(hwnd, IDC_CB_VJMODE, m_vj_mode);
  859. // Enumerate available adapters.
  860. UpdateAdapters(0); // fullscreen
  861. //-calls UpdateFSAdapterDispModes()
  862. //-which then calls UpdateDispModeMultiSampling(0).
  863. UpdateAdapters(1); // windowed
  864. //-skips UpdateFSAdapterDispModes() (not necessary for windowed mode)
  865. //-then calls UpdateDispModeMultiSampling(1).
  866. UpdateAdapters(3); // desktop
  867. //-skips UpdateFSAdapterDispModes() (not necessary for fake fullscreen mode)
  868. //-then calls UpdateDispModeMultiSampling(2).
  869. UpdateMaxFps(0);
  870. UpdateMaxFps(1);
  871. UpdateMaxFps(3); // desktop
  872. // disable a few things if fake fullscreen mode enabled:
  873. EnableWindow(GetDlgItem(hwnd, IDC_DISP_MODE), !m_fake_fullscreen_mode);
  874. //EnableWindow(GetDlgItem(hwnd, IDC_FSMS), !m_fake_fullscreen_mode);
  875. }
  876. break;
  877. case WM_DESTROY:
  878. {
  879. // read checkboxes
  880. m_start_fullscreen = DlgItemIsChecked(hwnd, IDC_CB_FS );
  881. m_start_desktop = DlgItemIsChecked(hwnd, IDC_CB_DMS );
  882. m_fake_fullscreen_mode = DlgItemIsChecked(hwnd, IDC_CB_FAKE );
  883. m_show_press_f1_msg = DlgItemIsChecked(hwnd, IDC_CB_PRESS_F1_MSG);
  884. m_allow_page_tearing_w = DlgItemIsChecked(hwnd, IDC_CB_WPT );
  885. m_allow_page_tearing_fs= DlgItemIsChecked(hwnd, IDC_CB_FSPT );
  886. m_allow_page_tearing_dm= DlgItemIsChecked(hwnd, IDC_CB_DMSPT);
  887. m_minimize_winamp = DlgItemIsChecked(hwnd, IDC_CB_MIN );
  888. m_save_cpu = DlgItemIsChecked(hwnd, IDC_CB_SAVE_CPU );
  889. m_fix_slow_text = DlgItemIsChecked(hwnd, IDC_CB_FIXSLOWTEXT);
  890. m_vj_mode = DlgItemIsChecked(hwnd, IDC_CB_VJMODE);
  891. if (mod1.hwndParent && SendMessage(mod1.hwndParent,WM_WA_IPC,0,0) >= 0x2900)
  892. m_skin = DlgItemIsChecked(hwnd, IDC_CB_SKIN );
  893. // read all 3 adapters
  894. SaveAdapter(0);
  895. SaveAdapter(1);
  896. SaveAdapter(3);
  897. // read fullscreen display mode
  898. SaveDisplayMode();
  899. // read all 3 multisampling settings:
  900. SaveMultiSamp(0);
  901. SaveMultiSamp(1);
  902. SaveMultiSamp(3);
  903. // read all 3 max fps settings
  904. SaveMaxFps(0);
  905. SaveMaxFps(1);
  906. SaveMaxFps(3);
  907. }
  908. break;
  909. case WM_COMMAND:
  910. if (!g_ignore_clicks)
  911. {
  912. int id = LOWORD(wParam);
  913. g_ignore_clicks = 1;
  914. switch(id)
  915. {
  916. case ID_FONTS:
  917. WASABI_API_DIALOGBOXPARAMW(IDD_FONTDIALOG, hwnd, FontDialogProc, (LPARAM)this);
  918. break;
  919. case ID_DM_MORE:
  920. WASABI_API_DIALOGBOXPARAMW(IDD_DESKTOPMODE, hwnd, DesktopOptionsDialogProc, (LPARAM)this);
  921. break;
  922. case ID_DUALHEAD:
  923. WASABI_API_DIALOGBOXPARAMW(IDD_DUALHEAD, hwnd, DualheadDialogProc, (LPARAM)this);
  924. break;
  925. case IDC_ADAPTER_FS:
  926. SaveDisplayMode();
  927. SaveMultiSamp(FULLSCREEN);
  928. SaveAdapter(0);
  929. UpdateFSAdapterDispModes();
  930. break;
  931. case IDC_ADAPTER_W:
  932. SaveMultiSamp(WINDOWED);
  933. UpdateDispModeMultiSampling(WINDOWED);
  934. break;
  935. /*
  936. case IDC_ADAPTER_FFS:
  937. SaveMultiSamp(FAKE_FULLSCREEN);
  938. UpdateDispModeMultiSampling(FAKE_FULLSCREEN);
  939. break;
  940. */
  941. case IDC_ADAPTER_DMS:
  942. SaveMultiSamp(DESKTOP);
  943. UpdateDispModeMultiSampling(DESKTOP);
  944. break;
  945. case IDC_DISP_MODE:
  946. SaveMultiSamp(FULLSCREEN);
  947. UpdateDispModeMultiSampling(FULLSCREEN);
  948. break;
  949. case IDC_CB_WPT:
  950. SaveMultiSamp(WINDOWED);
  951. m_allow_page_tearing_w = DlgItemIsChecked(hwnd, IDC_CB_WPT);
  952. UpdateDispModeMultiSampling(WINDOWED);
  953. break;
  954. case IDC_CB_FSPT:
  955. SaveMultiSamp(FULLSCREEN);
  956. m_allow_page_tearing_fs = DlgItemIsChecked(hwnd, IDC_CB_FSPT);
  957. UpdateDispModeMultiSampling(FULLSCREEN);
  958. break;
  959. case IDC_CB_DMSPT:
  960. SaveMultiSamp(DESKTOP);
  961. m_allow_page_tearing_dm = DlgItemIsChecked(hwnd, IDC_CB_DMSPT);
  962. UpdateDispModeMultiSampling(DESKTOP);
  963. break;
  964. case IDC_CB_FS:
  965. m_start_fullscreen = DlgItemIsChecked(hwnd, IDC_CB_FS );
  966. if (m_start_fullscreen && m_start_desktop)
  967. {
  968. m_start_desktop = 0;
  969. CheckDlgButton(hwnd, IDC_CB_DMS, m_start_desktop);
  970. }
  971. break;
  972. case IDC_CB_DMS:
  973. m_start_desktop = DlgItemIsChecked(hwnd, IDC_CB_DMS );
  974. if (m_start_fullscreen && m_start_desktop)
  975. {
  976. m_start_fullscreen = 0;
  977. CheckDlgButton(hwnd, IDC_CB_FS, m_start_fullscreen);
  978. }
  979. break;
  980. case IDC_CB_FAKE:
  981. SaveMultiSamp(FULLSCREEN);
  982. m_fake_fullscreen_mode = DlgItemIsChecked(hwnd, IDC_CB_FAKE );
  983. EnableWindow(GetDlgItem(hwnd, IDC_DISP_MODE), !m_fake_fullscreen_mode);
  984. CheckDlgButton(hwnd, IDC_CB_FSPT, m_fake_fullscreen_mode ? m_allow_page_tearing_fs : 0);
  985. EnableWindow(GetDlgItem(hwnd, IDC_CB_FSPT), m_fake_fullscreen_mode ? 1 : 0);
  986. UpdateDispModeMultiSampling(FULLSCREEN);
  987. break;
  988. /*
  989. case IDC_CB_FFSPT:
  990. SaveMultiSamp(FAKE_FULLSCREEN);
  991. m_allow_page_tearing_fake_fs = DlgItemIsChecked(hwnd, IDC_CB_FFSPT);
  992. UpdateDispModeMultiSampling(FAKE_FULLSCREEN);
  993. break;
  994. */
  995. }
  996. g_ignore_clicks = 0;
  997. }
  998. break; // case WM_COMMAND
  999. case WM_HELP:
  1000. if (lParam)
  1001. {
  1002. HELPINFO *ph = (HELPINFO*)lParam;
  1003. wchar_t title[1024];
  1004. wchar_t buf[2048];
  1005. wchar_t ctrl_name[1024];
  1006. GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
  1007. RemoveSingleAmpersands(ctrl_name);
  1008. buf[0] = 0;
  1009. switch(ph->iCtrlId)
  1010. {
  1011. case ID_FONTS:
  1012. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1013. WASABI_API_LNGSTRINGW_BUF(IDS_FONTS_HELP, buf, 2048);
  1014. break;
  1015. case ID_DUALHEAD:
  1016. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1017. WASABI_API_LNGSTRINGW_BUF(IDS_DUAL_HEAD_HELP, buf, 2048);
  1018. break;
  1019. case IDC_W_MULTISAMPLING_CAPTION:
  1020. case IDC_FS_MULTISAMPLING_CAPTION:
  1021. case IDC_DMS_MULTISAMPLING_CAPTION:
  1022. //case IDC_FFS_MULTISAMPLING_CAPTION:
  1023. case IDC_WMS:
  1024. case IDC_FSMS:
  1025. case IDC_DMSMS:
  1026. //case IDC_FFSMS:
  1027. WASABI_API_LNGSTRINGW_BUF(IDS_MULTI_SAMPLING, title, 1024);
  1028. WASABI_API_LNGSTRINGW_BUF(IDS_MULTI_SAMPLING_HELP, buf, 2048);
  1029. break;
  1030. case IDC_W_MAXFPS:
  1031. case IDC_FS_MAXFPS:
  1032. case IDC_DMS_MAXFPS:
  1033. //case IDC_FFS_MAXFPS:
  1034. case IDC_W_MAXFPS_CAPTION:
  1035. case IDC_FS_MAXFPS_CAPTION:
  1036. case IDC_DMS_MAXFPS_CAPTION:
  1037. //case IDC_FFS_MAXFPS_CAPTION:
  1038. WASABI_API_LNGSTRINGW_BUF(IDS_MAX_FRAMERATE, title, 1024);
  1039. WASABI_API_LNGSTRINGW_BUF(IDS_MAX_FRAMERATE_HELP, buf, 2048);
  1040. break;
  1041. case IDC_CB_FAKE:
  1042. WASABI_API_LNGSTRINGW_BUF(IDS_FAKE_FULLSCREEN, title, 1024);
  1043. WASABI_API_LNGSTRINGW_BUF(IDS_FAKE_FULLSCREEN_HELP, buf, 2048);
  1044. break;
  1045. case IDC_ADAPTER_FS:
  1046. case IDC_FS_ADAPTER_CAPTION:
  1047. WASABI_API_LNGSTRINGW_BUF(IDS_FULLSCREEN_ADAPTER, title, 1024);
  1048. WASABI_API_LNGSTRINGW_BUF(IDS_FULLSCREEN_ADAPTER_HELP, buf, 2048);
  1049. break;
  1050. case IDC_ADAPTER_W:
  1051. case IDC_W_ADAPTER_CAPTION:
  1052. WASABI_API_LNGSTRINGW_BUF(IDS_WINDOWED_ADPATER, title, 1024);
  1053. WASABI_API_LNGSTRINGW_BUF(IDS_WINDOWED_ADPATER_HELP, buf, 2048);
  1054. break;
  1055. case IDC_ADAPTER_DMS:
  1056. case IDC_DMS_ADAPTER_CAPTION:
  1057. WASABI_API_LNGSTRINGW_BUF(IDS_DESKTOP_ADAPTER, title, 1024);
  1058. WASABI_API_LNGSTRINGW_BUF(IDS_DESKTOP_ADAPTER_HELP, buf, 2048);
  1059. break;
  1060. case IDC_DISP_MODE:
  1061. case IDC_DISP_MODE_CAPTION:
  1062. WASABI_API_LNGSTRINGW_BUF(IDS_FS_DISPLAY_MODE, title, 1024);
  1063. WASABI_API_LNGSTRINGW_BUF(IDS_FS_DISPLAY_MODE_HELP, buf, 2048);
  1064. break;
  1065. case IDC_CB_WPT:
  1066. case IDC_CB_FSPT:
  1067. case IDC_CB_DMSPT:
  1068. //case IDC_CB_FFSPT:
  1069. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
  1070. WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_X_CHECKBOX_HELP, buf, 2048);
  1071. break;
  1072. case IDC_CB_FS:
  1073. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
  1074. WASABI_API_LNGSTRINGW_BUF(IDS_FORCE_INTO_FS_MODE_HELP, buf, 2048);
  1075. break;
  1076. case IDC_CB_DMS:
  1077. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
  1078. WASABI_API_LNGSTRINGW_BUF(IDS_FORCE_INTO_DESKTOP_MODE_HELP, buf, 2048);
  1079. break;
  1080. case IDC_CB_PRESS_F1_MSG:
  1081. WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_F1, title, 1024);
  1082. WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_F1_HELP, buf, 2048);
  1083. break;
  1084. case IDC_CB_SKIN:
  1085. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
  1086. WASABI_API_LNGSTRINGW_BUF(IDS_CB_SKIN_HELP, buf, 2048);
  1087. break;
  1088. case IDC_CB_SAVE_CPU:
  1089. WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_CPU_CHECKBOX, title, 1024);
  1090. WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_CPU_CHECKBOX_HELP, buf, 2048);
  1091. break;
  1092. case IDC_CB_MIN:
  1093. WASABI_API_LNGSTRINGW_BUF(IDS_HELP_MINIMIZE_WINAMP, title, 1024);
  1094. WASABI_API_LNGSTRINGW_BUF(IDS_HELP_MINIMIZE_WINAMP_HELP, buf, 2048);
  1095. break;
  1096. case IDC_CB_FIXSLOWTEXT:
  1097. WASABI_API_LNGSTRINGW_BUF(IDS_TRY_TO_FIX_SLOW_TEXT, title, 1024);
  1098. WASABI_API_LNGSTRINGW_BUF(IDS_TRY_TO_FIX_SLOW_TEXT_HELP, buf, 2048);
  1099. break;
  1100. case IDC_CB_VJMODE:
  1101. WASABI_API_LNGSTRINGW_BUF(IDS_VJ_MODE, title, 1024);
  1102. WASABI_API_LNGSTRINGW_BUF(IDS_VJ_MODE_HELP, buf, 2048);
  1103. break;
  1104. case IDC_DMS_LABEL:
  1105. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
  1106. WASABI_API_LNGSTRINGW_BUF(IDS_DMS_LABEL_HELP, buf, 2048);
  1107. break;
  1108. case IDC_FS_LABEL:
  1109. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
  1110. WASABI_API_LNGSTRINGW_BUF(IDS_FS_LABEL_HELP, buf, 2048);
  1111. break;
  1112. case IDC_W_LABEL:
  1113. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
  1114. WASABI_API_LNGSTRINGW_BUF(IDS_W_LABEL_HELP, buf, 2048);
  1115. break;
  1116. case ID_DM_MORE:
  1117. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
  1118. WASABI_API_LNGSTRINGW_BUF(IDS_DM_MORE_HELP, buf, 2048);
  1119. break;
  1120. }
  1121. if (buf[0])
  1122. MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1123. }
  1124. break; // case WM_HELP
  1125. }
  1126. return 0;
  1127. }
  1128. BOOL CALLBACK CPluginShell::ConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  1129. {
  1130. if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
  1131. SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
  1132. CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
  1133. if (p)
  1134. return p->PluginShellConfigDialogProc(hwnd, msg, wParam, lParam);
  1135. else
  1136. return FALSE;
  1137. }
  1138. BOOL CPluginShell::PluginShellConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  1139. {
  1140. #ifdef _DEBUG
  1141. OutputDebugMessage("CfgDlgProc: ", hwnd, msg, wParam, lParam);
  1142. #endif
  1143. switch (msg)
  1144. {
  1145. case WM_DESTROY:
  1146. EndConfig();
  1147. return 0;
  1148. case WM_INITDIALOG:
  1149. {
  1150. // Initialize all config panel global variables:
  1151. if (!InitConfig(hwnd))
  1152. {
  1153. wchar_t title[64];
  1154. MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_INITCONFIG_FAILED),
  1155. WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
  1156. MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1157. EndConfig();
  1158. int id=LOWORD(wParam);
  1159. EndDialog(hwnd,id);
  1160. return false;
  1161. }
  1162. // set window caption
  1163. SetWindowText( hwnd, WINDOWCAPTION );
  1164. // Test for DirectX 9 + start it
  1165. // note: if you don't call LoadLibrary here, and you're on a system
  1166. // where DX9 is missing, Direct3DCreate9() might crash; so call it.
  1167. int d3d9_already_loaded = (GetModuleHandle("d3d9.dll") != NULL) ? 1 : 0;
  1168. if (!d3d9_already_loaded)
  1169. g_hmod_d3d9 = LoadLibrary("d3d9.dll");
  1170. if ( (!d3d9_already_loaded && !g_hmod_d3d9) ||
  1171. !(g_lpDX = Direct3DCreate9(D3D_SDK_VERSION))
  1172. )
  1173. {
  1174. MissingDirectX(hwnd);
  1175. EndConfig();
  1176. int id=LOWORD(wParam);
  1177. EndDialog(hwnd,id);
  1178. return false;
  1179. }
  1180. if (!g_hmod_d3dx9)
  1181. g_hmod_d3dx9 = FindD3DX9(GetWinampWindow());
  1182. if ((!g_hmod_d3dx9))
  1183. {
  1184. MissingDirectX(hwnd);
  1185. EndConfig();
  1186. int id=LOWORD(wParam);
  1187. EndDialog(hwnd,id);
  1188. return false;
  1189. }
  1190. // enable the 'view website' button only if plugin author has #defined a URL (in defines.h):
  1191. #ifndef PLUGIN_WEB_URL
  1192. ShowWindow(GetDlgItem(hwnd, ID_WEB), SW_HIDE);
  1193. #else
  1194. if (wcslen(PLUGIN_WEB_URL)==0)
  1195. ShowWindow(GetDlgItem(hwnd, ID_WEB), SW_HIDE);
  1196. #endif
  1197. // enable the 'view docs' button only if plugin author has #defined a filename (in defines.h):
  1198. #ifndef DOCFILE
  1199. ShowWindow(GetDlgItem(hwnd, ID_DOCS), SW_HIDE);
  1200. #else
  1201. if (wcslen(DOCFILE)==0)
  1202. ShowWindow(GetDlgItem(hwnd, ID_DOCS), SW_HIDE);
  1203. #endif
  1204. // set contents of IDC_SZ_ABOUT
  1205. wchar_t about[256];
  1206. StringCchPrintfW(about, 256, WASABI_API_LNGSTRINGW(IDS_ABOUT_STRING), LONGNAMEW, AUTHOR_NAME, COPYRIGHT);
  1207. SetDlgItemTextW(hwnd, IDC_SZ_ABOUT, about);
  1208. // initialize tab control:
  1209. {
  1210. HWND tabWnd = GetDlgItem(hwnd,IDC_TABS);
  1211. // Add Tabs:
  1212. if (!AddButton(0, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_1)) ||
  1213. !AddButton(1, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_2)) ||
  1214. !AddButton(2, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_3)) ||
  1215. !AddButton(3, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_4)) ||
  1216. !AddButton(4, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_5)) ||
  1217. !AddButton(5, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_6)) ||
  1218. !AddButton(6, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_7)) ||
  1219. !AddButton(7, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_8)))
  1220. {
  1221. wchar_t title[64];
  1222. MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_LOAD_TABS),
  1223. WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
  1224. MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1225. EndConfig();
  1226. int id=LOWORD(wParam);
  1227. EndDialog(hwnd,id);
  1228. return false;
  1229. }
  1230. // Simulate selection of the first tab.
  1231. int last_tab = GetPrivateProfileIntW(L"settings",L"last_tab",0,m_szConfigIniFile);
  1232. TabCtrl_SetCurSel(tabWnd, last_tab);
  1233. OnTabChanged(last_tab);
  1234. }
  1235. g_ignore_clicks = 0;
  1236. SetFocus(hwnd);
  1237. }
  1238. return 0;
  1239. case WM_NOTIFY:
  1240. if (!g_ignore_clicks)
  1241. {
  1242. LPNMHDR pnmh = (LPNMHDR)lParam;
  1243. switch(pnmh->code)
  1244. {
  1245. case TCN_SELCHANGE:
  1246. OnTabChanged(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)));
  1247. break;
  1248. }
  1249. }
  1250. break;
  1251. case WM_COMMAND:
  1252. if (!g_ignore_clicks)
  1253. {
  1254. int id = LOWORD(wParam);
  1255. switch(id)
  1256. {
  1257. case IDOK:
  1258. // kill current tab window, so that its settings get read
  1259. WritePrivateProfileIntW(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)),L"last_tab",m_szConfigIniFile,L"settings");
  1260. OnTabChanged(-1);
  1261. // then save new config
  1262. WriteConfig();
  1263. EndDialog(hwnd,id);
  1264. return 0;
  1265. case IDCANCEL:
  1266. WritePrivateProfileIntW(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)),L"last_tab",m_szConfigIniFile,L"settings");
  1267. EndDialog(hwnd,id);
  1268. return 0;
  1269. case ID_DOCS:
  1270. {
  1271. wchar_t szPath[512], szFile[512];
  1272. lstrcpyW(szPath, m_szPluginsDirPath);
  1273. lstrcpyW(szFile, szPath);
  1274. lstrcatW(szFile, DOCFILE);
  1275. intptr_t ret = myOpenURL(0,szFile);
  1276. if (ret <= 32)
  1277. {
  1278. wchar_t buf[1024];
  1279. switch(ret)
  1280. {
  1281. case SE_ERR_FNF:
  1282. case SE_ERR_PNF:
  1283. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_DOCUMENTATION_FILE_NOT_FOUND), szFile);
  1284. break;
  1285. case SE_ERR_ACCESSDENIED:
  1286. case SE_ERR_SHARE:
  1287. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_DENIED), szFile);
  1288. break;
  1289. case SE_ERR_NOASSOC:
  1290. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_DUE_TO_NO_ASSOC), szFile);
  1291. break;
  1292. default:
  1293. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_CODE_X), szFile, ret);
  1294. break;
  1295. }
  1296. MessageBoxW(hwnd, buf, WASABI_API_LNGSTRINGW(IDS_ERROR_OPENING_DOCUMENTATION), MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1297. }
  1298. }
  1299. break;
  1300. case ID_WEB:
  1301. {
  1302. intptr_t ret = myOpenURL(NULL, PLUGIN_WEB_URL);
  1303. if (ret <= 32)
  1304. {
  1305. wchar_t buf[1024];
  1306. switch(ret)
  1307. {
  1308. case SE_ERR_FNF:
  1309. case SE_ERR_PNF:
  1310. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_URL_COULD_NOT_OPEN), PLUGIN_WEB_URL);
  1311. break;
  1312. case SE_ERR_ACCESSDENIED:
  1313. case SE_ERR_SHARE:
  1314. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_WAS_DENIED), PLUGIN_WEB_URL);
  1315. break;
  1316. case SE_ERR_NOASSOC:
  1317. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_DUE_TO_NO_ASSOC), PLUGIN_WEB_URL);
  1318. break;
  1319. default:
  1320. StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_CODE_X), PLUGIN_WEB_URL, ret);
  1321. break;
  1322. }
  1323. MessageBoxW(hwnd, buf, WASABI_API_LNGSTRINGW(IDS_ERROR_OPENING_URL), MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1324. }
  1325. }
  1326. break;
  1327. case ID_DEFAULTS:
  1328. wchar_t title[64];
  1329. if (IDYES == MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_RESTORE_ALL_DEFAULTS),
  1330. WASABI_API_LNGSTRINGW_BUF(IDS_RESTORE_ALL_DEFAULTS_TITLE, title, 64),
  1331. MB_YESNO|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL))
  1332. {
  1333. DeleteFileW(m_szConfigIniFile);
  1334. Sleep(100);
  1335. EndDialog(hwnd,id);
  1336. }
  1337. break;
  1338. default:
  1339. return 0;
  1340. }
  1341. }
  1342. break; // case WM_COMMAND
  1343. case WM_HELP:
  1344. if (lParam)
  1345. {
  1346. HELPINFO *ph = (HELPINFO*)lParam;
  1347. wchar_t title[1024];
  1348. wchar_t buf[2048];
  1349. wchar_t ctrl_name[1024];
  1350. GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
  1351. RemoveSingleAmpersands(ctrl_name);
  1352. buf[0] = 0;
  1353. switch(ph->iCtrlId)
  1354. {
  1355. case IDOK:
  1356. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1357. WASABI_API_LNGSTRINGW_BUF(IDS_OK_HELP, buf, 2048);
  1358. break;
  1359. case IDCANCEL:
  1360. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1361. WASABI_API_LNGSTRINGW_BUF(IDS_CANCEL_HELP, buf, 2048);
  1362. break;
  1363. case ID_DEFAULTS:
  1364. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1365. WASABI_API_LNGSTRINGW_BUF(IDS_RESTORE_DEFAULTS_HELP, buf, 2048);
  1366. break;
  1367. case ID_DOCS:
  1368. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1369. WASABI_API_LNGSTRINGW_BUF(IDS_DOCUMENTATION_BUTTON_HELP, buf, 2048);
  1370. break;
  1371. case ID_WEB:
  1372. StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
  1373. WASABI_API_LNGSTRINGW_BUF(IDS_VIEW_ONLINE_DOCS_HELP, buf, 2048);
  1374. break;
  1375. default:
  1376. return 0;
  1377. }
  1378. if (buf[0])
  1379. MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
  1380. }
  1381. break; // case WM_HELP
  1382. }
  1383. return 0;
  1384. }