OSDN Git Service

Merge UnkoTim220
[timidity41/timidity41.git] / interface / w32g_i.c
1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2018 Masanao Izumo <iz@onicos.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20     w32g_main.c: Written by Daisuke Aoki <dai@y7.net>
21                  Modified by Masanao Izumo <iz@onicos.co.jp>
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif /* HAVE_CONFIG_H */
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <process.h>
30 #include <stddef.h>
31 #include <windows.h>
32 #include <mmsystem.h>
33 #undef RC_NONE
34 #include <shlobj.h>
35 // #include <prsht.h>
36 #include <commctrl.h>
37 #ifndef NO_STRING_H
38 #include <string.h>
39 #else
40 #include <strings.h>
41 #endif
42 #include <shlobj.h>
43
44 #include <windowsx.h>   /* There is no <windowsx.h> on CYGWIN.
45                          * Edit_* and ListBox_* are defined in
46                          * <windowsx.h>
47                          */
48
49 #include "timidity.h"
50 #include "common.h"
51 #include "instrum.h"
52 #include "playmidi.h"
53 #include "readmidi.h"
54 #include "output.h"
55 #include "controls.h"
56
57 #include "wrd.h"
58
59 #include "w32g.h"
60 #include "w32g_res.h"
61 #include "w32g_utl.h"
62 #include "w32g_ut2.h"
63 #include "w32g_pref.h"
64 #include "w32g_subwin.h"
65 ///r
66 #include "aq.h"
67 #ifdef INT_SYNTH
68 #include "w32g_int_synth_editor.h"      
69 #endif
70
71 #if defined(__CYGWIN32__) || defined(__MINGW32__)
72 #define WIN32GCC
73 WINAPI void InitCommonControls(void);
74 #endif
75
76 #if 0
77 #define GDI_LOCK() { \
78         ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_LOCK(%s: %d)", __FILE__, __LINE__ ); \
79         gdi_lock(); \
80 }
81 #define GDI_UNLOCK() { \
82         ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_UNLOCK(%s: %d)", __FILE__, __LINE__ ); \
83         gdi_unlock(); \
84 }
85 #else
86 #define GDI_LOCK() { gdi_lock(); }
87 #define GDI_UNLOCK() { gdi_unlock(); }
88 #endif
89
90 static void InitMainWnd(HWND hStartWnd);
91
92 static void ConsoleWndVerbosityApplySet(int num);
93 void ConsoleWndVerbosityApply(void);
94
95 void CanvasPaintAll(void);
96 void CanvasReset(void);
97 void CanvasClear(void);
98 void CanvasUpdate(int flag);
99 void CanvasReadPanelInfo(int flag);
100 void CanvasChange(int mode);
101 void MPanelPaintAll(void);
102 void MPanelReadPanelInfo(int flag);
103 void MPanelReset(void);
104 void MPanelUpdateAll(void);
105 void ClearConsoleWnd(void);
106 void InitListWnd(HWND hParentWnd);
107 void InitTracerWnd(HWND hParentWnd);
108 void InitWrdWnd(HWND hParentWnd);
109 void InitDocWnd(HWND hParentWnd);
110 void InitListSearchWnd(HWND hParentWnd);
111 void PutsDocWnd(char *str);
112 void ClearDocWnd(void);
113 static void DlgPlaylistSave(HWND hwnd);
114 static void DlgPlaylistOpen(HWND hwnd);
115 static void DlgDirOpen(HWND hwnd);
116 static void DlgUrlOpen(HWND hwnd);
117 static void DlgMidiFileOpen(HWND hwnd);
118 void VprintfEditCtlWnd(HWND hwnd, char *fmt, va_list argList);
119 void PutsEditCtlWnd(HWND hwnd, char *str);
120 void ClearEditCtlWnd(HWND hwnd);
121
122 int     w32gSaveDefaultPlaylist(void);
123
124
125 #ifndef CLR_INVALID
126 #define CLR_INVALID 0xffffffff
127 #endif /* CLR_INVALID */
128 extern int optind;
129
130 HINSTANCE hInst;
131 static int progress_jump = -1;
132 static HWND hMainWndScrollbarProgressWnd;
133 static HWND hMainWndScrollbarVolumeWnd;
134 static HWND hMainWndScrollbarProgressTTipWnd;
135 static HWND hMainWndScrollbarVolumeTTipWnd;
136
137 //#define W32G_VOLUME_MAX 300
138 #define W32G_VOLUME_MAX MAX_AMPLIFICATION
139
140 // HWND
141 HWND hMainWnd = 0;
142 HWND hDebugWnd = 0;
143 HWND hConsoleWnd = 0;
144 HWND hTracerWnd = 0;
145 HWND hDocWnd = 0;
146 HWND hListWnd = 0;
147 HWND hWrdWnd = 0;
148 HWND hSoundSpecWnd = 0;
149 HWND hDebugEditWnd = 0;
150 HWND hDocEditWnd = 0;
151 HWND hUrlWnd = 0;
152
153 // Process.
154 HANDLE hProcess = 0;
155
156 // Main Thread.
157 HANDLE hMainThread = 0;
158 HANDLE hPlayerThread = 0;
159 HANDLE hMainThreadInfo = 0;
160 DWORD dwMainThreadID = 0;
161 static volatile int wait_thread_flag = 1;
162 typedef struct MAINTHREAD_ARGS_ {
163         int *pArgc;
164         char ***pArgv;
165 } MAINTHREAD_ARGS;
166 void WINAPI MainThread(void *arglist);
167
168 // Window Thread
169 HANDLE hWindowThread = 0;
170 HANDLE hWindowThreadInfo = 0;
171
172 // Thread
173 volatile int ThreadNumMax = 0;
174
175 // Debug Thread
176 volatile int DebugThreadExit = 1;
177 volatile HANDLE hDebugThread = 0;
178 void DebugThreadInit(void);
179 void PrintfDebugWnd(char *fmt, ...);
180 void ClearDebugWnd(void);
181 void InitDebugWnd(HWND hParentWnd);
182
183 // Flags
184 int InitMinimizeFlag = 0;
185 int DebugWndStartFlag = 1;
186 int ConsoleWndStartFlag = 0;
187 int ListWndStartFlag = 0;
188 int TracerWndStartFlag = 0;
189 int DocWndStartFlag = 0;
190 int WrdWndStartFlag = 0;
191 int SoundSpecWndStartFlag = 0;
192
193 int DebugWndFlag = 1;
194 int ConsoleWndFlag = 1;
195 int ListWndFlag = 1;
196 int TracerWndFlag = 0;
197 int DocWndFlag = 1;
198 int WrdWndFlag = 0;
199 int SoundSpecWndFlag = 0;
200 ///r
201 int RestartTimidity = 0;
202 int ConsoleClearFlag = 0;
203
204 int WrdGraphicFlag;
205 int TraceGraphicFlag;
206
207 char *IniFile;
208 char *ConfigFile;
209 char *PlaylistFile;
210 char *PlaylistHistoryFile;
211 char *MidiFileOpenDir;
212 char *ConfigFileOpenDir;
213 char *PlaylistFileOpenDir;
214
215 ///r
216 // Priority
217 //int PlayerThreadPriority;
218 int MidiPlayerThreadPriority;
219 int MainThreadPriority;
220 int GUIThreadPriority;
221 int TracerThreadPriority;
222 int WrdThreadPriority;
223
224 // dir
225 int SeachDirRecursive = 0;      // \8dÄ\8bA\93I\83f\83B\83\8c\83N\83g\83\8a\8c\9f\8dõ 
226 // Ini File
227 int IniFileAutoSave = 1;        // INI \83t\83@\83C\83\8b\82Ì\8e©\93®\83Z\81[\83u
228
229 // misc
230 int DocMaxSize;
231 char *DocFileExt;
232
233 int AutoloadPlaylist = 0;
234 int AutosavePlaylist = 0;
235 int volatile save_playlist_once_before_exit_flag = 1;
236
237 static volatile int w32g_wait_for_init;
238 void w32g_send_rc(int rc, ptr_size_t value);
239 int w32g_lock_open_file = 0;
240
241 void TiMidityHeapCheck(void);
242
243 volatile DWORD dwWindowThreadID = -1;
244 void w32g_i_init(void)
245 {
246     ThreadNumMax++;
247     hProcess = GetCurrentProcess();
248     hWindowThread = GetCurrentThread();
249         dwWindowThreadID = GetCurrentThreadId();
250
251     InitCommonControls();
252
253 #ifdef W32GUI_DEBUG
254     DebugThreadInit();
255 #endif
256 }
257
258 int PlayerLanguage = LANGUAGE_ENGLISH;
259 //int PlayerLanguage = LANGUAGE_JAPANESE;
260 #define PInfoOK 1
261 long SetValue(int32 value, int32 min, int32 max)
262 {
263   int32 v = value;
264   if(v < min) v = min;
265   else if( v > max) v = max;
266   return v;
267 }
268
269 int w32gSecondTiMidity(int opt, int argc, char **argv);
270 int w32gSecondTiMidityExit(void);
271 int SecondMode = 1;
272
273 void FirstLoadIniFile(void);
274
275 #if defined(_MSC_VER) && !defined(TWSYNG32)
276 #ifndef TIM_CUI
277 extern void CmdLineToArgv(LPSTR lpCmdLine, int *argc, CHAR ***argv);
278 extern int win_main(int argc, char **argv); /* timidity.c */
279 int WINAPI
280 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
281 LPSTR lpCmdLine, int nCmdShow)
282 {
283         
284         int argc = 0;
285         CHAR **argv = NULL;
286         int errcode;
287         int i;
288         static int first = 0;
289
290         Sleep(100); // Restart\82Å\91O\83v\83\8d\83Z\83X\82Ì\8fI\97¹\91Ò\8b@
291 #ifdef _CRTDBG_MAP_ALLOC
292         _CrtSetDbgFlag(CRTDEBUGFLAGS);
293 #endif
294         CmdLineToArgv(lpCmdLine,&argc,&argv);
295 #if 0
296         FirstLoadIniFile();
297         if(w32gSecondTiMidity(SecondMode,argc,argv)==TRUE){
298                 int res = win_main(argc, argv);
299                 w32gSecondTiMidityExit();
300                 for(i = 0; i < argc; i ++) {
301                         safe_free(argv[i]);
302                 }
303                 safe_free(argv);
304                 return res;
305         } else {
306                 for(i = 0; i < argc; i ++) {
307                         safe_free(argv[i]);
308                 }
309                 safe_free(argv);
310                 return -1;
311         }
312 #else
313         wrdt=wrdt_list[0];
314         errcode = win_main(argc, argv);
315         for(i = 0; i < argc; i ++) {
316                 safe_free(argv[i]);
317         }
318         safe_free(argv);
319
320         if(RestartTimidity){
321                 PROCESS_INFORMATION pi;
322                 STARTUPINFO si;
323                 CHAR path[FILEPATH_MAX] = "";
324                 RestartTimidity = 0;
325                 memset(&si, 0, sizeof(si));
326                 si.cb  = sizeof(si);
327                 GetModuleFileName(hInstance, path, MAX_PATH);
328                 if(CreateProcess(path, lpCmdLine, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi) == FALSE)
329                         MessageBox(NULL, "Restart Error.", "TiMidity++ Win32GUI", MB_OK | MB_ICONEXCLAMATION);
330         }
331         return errcode;
332 #endif
333 }
334 #endif /* TIM_CUI */
335 #endif
336
337 // ***************************************************************************
338 // System Function
339
340 void CALLBACK KillProcess(UINT IDEvent, UINT uReserved, DWORD_PTR dwUser,
341         DWORD_PTR dwReserved1, DWORD_PTR dwReserved2)
342 {
343         exit(0);
344         //      ExitProcess(0);
345 }
346
347 void OnExit(void)
348 {
349 #ifdef W32GUI_DEBUG
350         PrintfDebugWnd("PostQuitMessage\n");
351         Sleep(200);
352 #endif
353         PostQuitMessage(0);
354 }
355
356 static int OnExitReadyWait = 200;
357 void OnExitReady(void)
358 {
359         int i;
360 #ifdef W32GUI_DEBUG
361         PrintfDebugWnd("OnExitReady: Start.\n");
362 #endif
363     w32g_send_rc(RC_STOP, 0);
364
365         /* Exit after 10 sec. */
366         
367         timeSetEvent(10000, 1000, KillProcess, 0, TIME_ONESHOT);
368
369         /* Wait really stopping to play */
370         i = 1000/OnExitReadyWait; /* 1 sec. */
371     while(w32g_play_active && i-- > 0)
372         {
373                 Sleep(OnExitReadyWait);
374                 VOLATILE_TOUCH(w32g_play_active);
375         }
376
377 #ifdef W32GUI_DEBUG
378         PrintfDebugWnd("OnExitReady: End.\n");
379 #endif
380 }
381
382 void OnQuit(void)
383 {
384         SendMessage(hMainWnd, WM_CLOSE, 0, 0);
385 }
386
387
388 // ***************************************************************************
389 // Start Window
390 // \91å\8c³\82Ì\83E\83B\83\93\83h\83E\82Ì\92n\88Ê\82ÍMain Window\82É\8f÷\82è\81A\8d¡\82Å\82Í\82½\82¾\82Ì\8f\89\8aú\89»\8aÖ\90\94
391
392 void InitStartWnd(int nCmdShow)
393 {
394         InitMainWnd(NULL);
395         InitConsoleWnd(hMainWnd);
396         InitListWnd(hMainWnd);
397         InitTracerWnd(hMainWnd);
398         InitDocWnd(hMainWnd);
399         InitWrdWnd(hMainWnd);
400         InitSoundSpecWnd(hMainWnd);
401
402     hMainWndScrollbarProgressWnd = GetDlgItem(hMainWnd, IDC_SCROLLBAR_PROGRESS);
403         hMainWndScrollbarVolumeWnd = GetDlgItem(hMainWnd, IDC_SCROLLBAR_VOLUME);
404         EnableScrollBar(hMainWndScrollbarVolumeWnd, SB_CTL,ESB_ENABLE_BOTH);
405         SetScrollRange(hMainWndScrollbarVolumeWnd, SB_CTL,
406                        0, W32G_VOLUME_MAX, TRUE);
407 ///r
408         SetScrollPos(hMainWndScrollbarVolumeWnd, SB_CTL,
409                      W32G_VOLUME_MAX - output_amplification, TRUE);
410 }
411
412 /*****************************************************************************/
413 // Main Window
414
415 #define SWS_EXIST               0x0001
416 #define SWS_ICON                0x0002
417 #define SWS_HIDE                0x0004
418 typedef struct SUBWINDOW_ {
419         HWND *hwnd;
420         int status;
421 }       SUBWINDOW;
422 SUBWINDOW subwindow[] =
423 {
424   {&hConsoleWnd,0},
425   {&hListWnd,0},
426   {&hTracerWnd,0},
427   {&hDocWnd,0},
428   {&hWrdWnd,0},
429   {&hSoundSpecWnd,0},
430   {NULL,0}
431 };
432
433 int SubWindowMax = 5;
434 SUBWINDOW SubWindowHistory[] =
435 {
436   {&hConsoleWnd,0},
437   {&hListWnd,0},
438   {&hTracerWnd,0},
439   {&hDocWnd,0},
440   {&hWrdWnd,0},
441   {&hSoundSpecWnd,0},
442   {NULL,0}
443 };
444
445 MAINWNDINFO MainWndInfo;
446
447 static TOOLINFO SBVolumeTooltipInfo, SBProgressTooltipInfo;
448 static TCHAR SBVolumeTooltipText[8], // "0000 %\0"
449              SBProgressTooltipText[20]; // "000:00:00/000:00:00\0"
450
451 LRESULT CALLBACK MainProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
452 void update_subwindow(void);
453 void OnShow(void);
454 void OnHide(void);
455
456 static int MainWndInfoReset(HWND hwnd);
457 static int MainWndInfoApply(void);
458
459 extern void reload_cfg(void);
460
461
462 ///r
463 /*
464 create top-level menu / system menu
465 override w32g_res.rc IDM_MENU_MAIN IDM_MENU_MAIN_EN
466 \8d\80\96Ú\82Ì\95Ï\8dX\82ª\89Â\94\\82É\82È\82Á\82½\82Ì\82Å\83\8a\83\\81[\83X\83\81\83j\83\85\81[\82Í\83C\83~\82È\82µ\82É\81E\81E
467 */
468 // MENU MODULE 
469 #define IDM_MODULE 42000 // MainProc() sort ID
470 static HMENU hMenuModule;
471 // MENU OUTPUT
472 #define IDM_OUTPUT 41000 // MainProc() sort ID
473 #define IDM_OUTPUT_OPTIONS 41099 // MainProc() sort ID
474 static const size_t outputItemStart = 2;
475 static HMENU hMenuOutput;
476
477 static void InitMainMenu(HWND hWnd)
478 {
479         HMENU hMenu, hMenuFile, hMenuConfig, hMenuWindow, hMenuHelp;
480         HMENU hSystemMenu;
481         MENUITEMINFO mii;
482         int i;
483
484         // top-level menu
485         hMenu = GetMenu(hWnd);
486         if (hMenu != NULL)      {DestroyMenu (hMenu);}
487         hMenu = CreateMenu();
488         hMenuFile = CreateMenu();
489         hMenuConfig = CreateMenu();
490         hMenuWindow = CreateMenu();
491         hMenuModule = CreateMenu();
492         hMenuOutput = CreateMenu();
493         hMenuHelp = CreateMenu();
494         mii.cbSize = sizeof (MENUITEMINFO);
495         mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
496         mii.fType = MFT_STRING;
497         if (PlayerLanguage == LANGUAGE_JAPANESE) {
498                 mii.hSubMenu = hMenuFile;
499                 mii.dwTypeData = TEXT("\83t\83@\83C\83\8b(&F)");
500                 InsertMenuItem(hMenu, 0, TRUE, &mii);
501                 mii.hSubMenu = hMenuConfig;
502                 mii.dwTypeData = TEXT("\90Ý\92è(&C)");
503                 InsertMenuItem(hMenu, 1, TRUE, &mii);
504                 mii.hSubMenu = hMenuWindow;
505                 mii.dwTypeData = TEXT("\83E\83B\83\93\83h\83E(&W)");
506                 InsertMenuItem(hMenu, 2, TRUE, &mii);
507                 mii.hSubMenu = hMenuModule;
508                 mii.dwTypeData = TEXT("\83\82\83W\83\85\81[\83\8b(&M)");
509                 InsertMenuItem(hMenu, 3, TRUE, &mii);
510                 mii.hSubMenu = hMenuOutput;
511                 mii.dwTypeData = TEXT("\8fo\97Í(&O)");
512                 InsertMenuItem(hMenu, 4, TRUE, &mii);
513                 mii.hSubMenu = hMenuHelp;
514                 mii.dwTypeData = TEXT("\83w\83\8b\83v(&H)");
515                 InsertMenuItem(hMenu, 5, TRUE, &mii);
516                 // File
517                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENFILE, TEXT("\83t\83@\83C\83\8b\82ð\8aJ\82­(&F)"));
518                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENDIR, TEXT("\83t\83H\83\8b\83_\82ð\8aJ\82­(&D)"));
519 #ifdef SUPPORT_SOCKET
520                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENURL, TEXT("URL \82ð\8aJ\82­(&U)"));
521 #endif
522                 AppendMenu(hMenuFile, MF_SEPARATOR, 0, 0);
523                 AppendMenu(hMenuFile, MF_STRING, IDM_MFLOADPLAYLIST, TEXT("\83v\83\8c\83C\83\8a\83X\83g\82ð\8aJ\82­(&P)"));
524                 AppendMenu(hMenuFile, MF_STRING, IDM_MFSAVEPLAYLISTAS, TEXT("\83v\83\8c\83C\83\8a\83X\83g\82ð\95Û\91¶(&S)"));
525                 AppendMenu(hMenuFile, MF_SEPARATOR, 0, 0);
526                 AppendMenu(hMenuFile, MF_STRING, IDM_MFRESTART, TEXT("\8dÄ\8bN\93®\81i&R)"));
527                 AppendMenu(hMenuFile, MF_STRING, IDM_MFEXIT, TEXT("\8fI\97¹(&X)"));
528                 // Config
529                 AppendMenu(hMenuConfig, MF_STRING, IDM_SETTING, TEXT("\8fÚ\8d×\90Ý\92è(&P)"));
530                 AppendMenu(hMenuConfig, MF_SEPARATOR, 0, 0);
531                 AppendMenu(hMenuConfig, MF_STRING, IDM_MCLOADINIFILE, TEXT("\90Ý\92è\93Ç\8d\9e(&L)"));
532                 AppendMenu(hMenuConfig, MF_STRING, IDM_MCSAVEINIFILE, TEXT("\90Ý\92è\95Û\91¶(&S)"));
533                 AppendMenu(hMenuConfig, MF_SEPARATOR, 0, 0);
534                 AppendMenu(hMenuConfig, MF_STRING, IDM_FORCE_RELOAD, TEXT("cfg\8b­\90§\8dÄ\93Ç\8d\9e(&F)"));
535                 // Window
536         AppendMenu(hMenuWindow, MF_STRING, IDM_MWPLAYLIST, TEXT("\83v\83\8c\83C\83\8a\83X\83g(&L)"));
537         AppendMenu(hMenuWindow, MF_STRING, IDM_MWTRACER, TEXT("\83g\83\8c\81[\83T(&T)"));
538         AppendMenu(hMenuWindow, MF_STRING, IDM_MWDOCUMENT, TEXT("\83h\83L\83\85\83\81\83\93\83g(&D)"));
539         AppendMenu(hMenuWindow, MF_STRING, IDM_MWWRDTRACER, TEXT("WRD(&W)"));
540         AppendMenu(hMenuWindow, MF_STRING, IDM_MWCONSOLE, TEXT("\83R\83\93\x83\x5C\81[\83\8b(&C)"));   // \83R\83\93\83\\81[\83\8b
541 #ifdef VST_LOADER_ENABLE
542         AppendMenu(hMenuWindow, MF_STRING, IDM_MWVSTMGR, TEXT("VST\83}\83l\81[\83W\83\83(&V)"));
543 #endif /* VST_LOADER_ENABLE */
544 #ifdef SUPPORT_SOUNDSPEC
545         AppendMenu(hMenuWindow, MF_STRING, IDM_MWSOUNDSPEC, TEXT("\83X\83y\83N\83g\83\8d\83O\83\89\83\80(&S)"));
546 #endif
547 #ifdef INT_SYNTH
548         AppendMenu(hMenuWindow, MF_STRING, IDM_MWISEDITOR, TEXT("\93à\91 \83V\83\93\83Z\83G\83f\83B\83^(&E)"));
549 #endif
550                 // Help
551         AppendMenu(hMenuHelp, MF_STRING, IDM_MHONLINEHELP, TEXT("\83I\83\93\83\89\83C\83\93\83w\83\8b\83v(&O)"));
552         AppendMenu(hMenuHelp, MF_STRING, IDM_MHONLINEHELPCFG, TEXT("\83R\83\93\83t\83B\83O\83t\83@\83C\83\8b\8fÚ\89ð(&C)"));
553         AppendMenu(hMenuHelp, MF_STRING, IDM_MHBTS, TEXT("\83o\83O\95ñ\8d\90\8f\8a(&B)"));
554                 AppendMenu(hMenuHelp, MF_SEPARATOR, 0, 0);
555         AppendMenu(hMenuHelp, MF_STRING, IDM_MHTIMIDITY, TEXT("TiMidity++\82É\82Â\82¢\82Ä(&T)"));
556         AppendMenu(hMenuHelp, MF_STRING, IDM_MHVERSION, TEXT("\83o\81[\83W\83\87\83\93\8fî\95ñ(&V)"));
557                 AppendMenu(hMenuHelp, MF_SEPARATOR, 0, 0);
558         AppendMenu(hMenuHelp, MF_STRING, IDM_MHSUPPLEMENT, TEXT("\95â\91«(&S)"));
559         }else{
560                 mii.hSubMenu = hMenuFile;
561                 mii.dwTypeData = TEXT("File(&F)");
562                 InsertMenuItem(hMenu, 0, TRUE, &mii);
563                 mii.hSubMenu = hMenuConfig;
564                 mii.dwTypeData = TEXT("Config(&C)");
565                 InsertMenuItem(hMenu, 1, TRUE, &mii);
566                 mii.hSubMenu = hMenuWindow;
567                 mii.dwTypeData = TEXT("Window(&W)");
568                 InsertMenuItem(hMenu, 2, TRUE, &mii);
569                 mii.hSubMenu = hMenuModule;
570                 mii.dwTypeData = TEXT("Module(&M)");
571                 InsertMenuItem(hMenu, 3, TRUE, &mii);
572                 mii.hSubMenu = hMenuOutput;
573                 mii.dwTypeData = TEXT("Output(&O)");
574                 InsertMenuItem(hMenu, 4, TRUE, &mii);
575                 mii.hSubMenu = hMenuHelp;
576                 mii.dwTypeData = TEXT("Help(&H)");
577                 InsertMenuItem(hMenu, 5, TRUE, &mii);
578                 // File
579                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENFILE, TEXT("Open File(&F)"));
580                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENDIR, TEXT("Open Directory(&D)"));
581 #ifdef SUPPORT_SOCKET
582                 AppendMenu(hMenuFile, MF_STRING, IDM_MFOPENURL, TEXT("Open Internet URL(&U)"));
583 #endif
584                 AppendMenu(hMenuFile, MF_SEPARATOR, 0, 0);
585                 AppendMenu(hMenuFile, MF_STRING, IDM_MFLOADPLAYLIST, TEXT("Load Playlist(&P)"));
586                 AppendMenu(hMenuFile, MF_STRING, IDM_MFSAVEPLAYLISTAS, TEXT("Save Playlist as(&S)"));
587                 AppendMenu(hMenuFile, MF_SEPARATOR, 0, 0);
588                 AppendMenu(hMenuFile, MF_STRING, IDM_MFRESTART, TEXT("Restart(&R)"));
589                 AppendMenu(hMenuFile, MF_STRING, IDM_MFEXIT, TEXT("Exit(&X)"));
590                 // Config
591                 AppendMenu(hMenuConfig, MF_STRING, IDM_SETTING, TEXT("Preference(&P)"));
592                 AppendMenu(hMenuConfig, MF_SEPARATOR, 0, 0);
593                 AppendMenu(hMenuConfig, MF_STRING, IDM_MCLOADINIFILE, TEXT("Load ini file(&L)"));
594                 AppendMenu(hMenuConfig, MF_STRING, IDM_MCSAVEINIFILE, TEXT("Save ini file(&S)"));
595                 AppendMenu(hMenuConfig, MF_SEPARATOR, 0, 0);
596                 AppendMenu(hMenuConfig, MF_STRING, IDM_FORCE_RELOAD, TEXT("Reload cfg file(&F)"));
597                 // Window
598         AppendMenu(hMenuWindow, MF_STRING, IDM_MWPLAYLIST, TEXT("Play List(&L)"));
599         AppendMenu(hMenuWindow, MF_STRING, IDM_MWTRACER, TEXT("Tracer(&T)"));
600         AppendMenu(hMenuWindow, MF_STRING, IDM_MWDOCUMENT, TEXT("Document(&D)"));
601         AppendMenu(hMenuWindow, MF_STRING, IDM_MWWRDTRACER, TEXT("Wrd tracer(&W)"));
602         AppendMenu(hMenuWindow, MF_STRING, IDM_MWCONSOLE, TEXT("Console(&C)"));
603 #ifdef VST_LOADER_ENABLE
604         AppendMenu(hMenuWindow, MF_STRING, IDM_MWVSTMGR, TEXT("VST Manager(&V)"));
605 #endif /* VST_LOADER_ENABLE */
606 #ifdef HAVE_SOUNDSPEC
607         AppendMenu(hMenuWindow, MF_STRING, IDM_MWSOUNDSPEC, TEXT("Sound Spectrogram(&S)"));
608 #endif
609 #ifdef INT_SYNTH
610         AppendMenu(hMenuWindow, MF_STRING, IDM_MWISEDITOR, TEXT("Internal Synth Editor(&E)"));
611 #endif
612                 // Help
613         AppendMenu(hMenuHelp, MF_STRING, IDM_MHONLINEHELP, TEXT("Online Help(&O)"));
614         AppendMenu(hMenuHelp, MF_STRING, IDM_MHBTS, TEXT("Bug Tracking System(&B)"));
615                 AppendMenu(hMenuHelp, MF_SEPARATOR, 0, 0);
616         AppendMenu(hMenuHelp, MF_STRING, IDM_MHTIMIDITY, TEXT("TiMidity++(&T)"));
617         AppendMenu(hMenuHelp, MF_STRING, IDM_MHVERSION, TEXT("Version(&V)"));
618                 AppendMenu(hMenuHelp, MF_SEPARATOR, 0, 0);
619         AppendMenu(hMenuHelp, MF_STRING, IDM_MHSUPPLEMENT, TEXT("Supplement(&S)"));
620         }
621         // Module
622         for (i = 0; i < module_list_num; i++) {
623                 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
624                 mii.wID = IDM_MODULE + i;
625                 mii.fType = MFT_STRING;
626                 if (st_temp->opt_default_module == module_list[i].num) {
627                         mii.fState = MFS_CHECKED;
628                 } else {
629                         mii.fState = MFS_UNCHECKED;
630                 }
631                 if (i > 0 && i % (module_list_num / 2) == 0)
632                         mii.fType |= MFT_MENUBARBREAK;
633                 mii.dwTypeData = module_list[i].name;
634                 InsertMenuItem(hMenuModule, i, TRUE, &mii);
635         }
636         // Output
637         mii.fMask = MIIM_TYPE | MIIM_ID;
638         mii.wID = IDM_OUTPUT_OPTIONS;
639         mii.fType = MFT_STRING;
640         if (PlayerLanguage == LANGUAGE_JAPANESE) {
641                 mii.dwTypeData = "\83I\83v\83V\83\87\83\93(&O)";
642         } else {
643                 mii.dwTypeData = "&Options";
644         }
645         InsertMenuItem(hMenuOutput, 0, TRUE, &mii);
646         mii.fMask = MIIM_TYPE;
647         mii.fType = MFT_SEPARATOR;
648         InsertMenuItem(hMenuOutput, 1, TRUE, &mii);
649         for (i = 0; play_mode_list[i] != 0; i++) {
650                 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
651                 mii.wID = IDM_OUTPUT + i;
652                 mii.fType = MFT_STRING;
653                 if (st_temp->opt_playmode[0] == play_mode_list[i]->id_character) {
654                         mii.fState = MFS_CHECKED;
655                 } else {
656                         mii.fState = MFS_UNCHECKED;
657                 }
658                 mii.dwTypeData = play_mode_list[i]->id_name;
659                 InsertMenuItem(hMenuOutput, outputItemStart + i, TRUE, &mii);
660         }       
661         SetMenu(hWnd , hMenu);
662         // system menu
663         hSystemMenu = GetSystemMenu(hWnd, FALSE);
664         RemoveMenu(hSystemMenu,SC_MAXIMIZE,MF_BYCOMMAND);
665         //RemoveMenu(hSystemMenu,SC_SIZE,MF_BYCOMMAND); // comment out for Resize MainWindow 
666         EnableMenuItem(hSystemMenu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
667         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, 0); // 7
668         InsertMenu(hSystemMenu, 0, MF_BYPOSITION, SC_SCREENSAVE, "Screen Saver"); // 6
669         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, 0); // 5
670         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_STRING, IDM_STOP, "Stop"); // 4
671         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_STRING, IDM_PAUSE, "Pause"); // 3
672         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_STRING, IDM_PREV, "Prev"); // 2
673         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_STRING, IDM_NEXT, "Next"); // 1
674         InsertMenu(hSystemMenu, 0, MF_BYPOSITION | MF_STRING, IDM_PLAY, "Play"); // 0   
675
676         DrawMenuBar(hWnd);
677 }
678
679 static void UpdateModuleMenu(HWND hWnd, UINT wId)
680 {
681         MENUITEMINFO mii;
682         int i, num = -1, oldnum;
683
684         for (i = 0; i < module_list_num; i++) {
685                 mii.cbSize = sizeof (MENUITEMINFO);
686                 mii.fMask = MIIM_STATE | MIIM_ID;
687                 GetMenuItemInfo(hMenuModule, i, TRUE, &mii);
688                 if (wId == mii.wID) {
689                         mii.fState = MFS_CHECKED;
690                         num = i;
691                 } else {
692                         mii.fState = MFS_UNCHECKED;
693                 }
694                 SetMenuItemInfo(hMenuModule, i, TRUE, &mii);
695                 if (st_temp->opt_default_module == module_list[i].num) {
696                         oldnum = i;
697                 }
698         }
699 //      if (!w32g_play_active && num != oldnum) {
700         if (num != oldnum) {
701                 if (num >= 0) {st_temp->opt_default_module = module_list[num].num;}
702                 else {st_temp->opt_default_module = MODULE_TIMIDITY_DEFAULT;}
703                 PrefSettingApplyReally();
704         }
705 }
706
707 static void UpdateOutputMenu(HWND hWnd, UINT wId)
708 {
709         MENUITEMINFOA mii;
710         int i, num = -1, oldnum;
711
712         for (i = 0; play_mode_list[i] != 0; i++) {
713                 mii.cbSize = sizeof(MENUITEMINFOA);
714                 mii.fMask = MIIM_STATE | MIIM_ID;
715                 GetMenuItemInfo(hMenuOutput, outputItemStart + i, TRUE, &mii);
716                 if (wId == mii.wID) {
717                         mii.fState = MFS_CHECKED;
718                         num = i;
719                 } else { mii.fState = MFS_UNCHECKED; }
720                 SetMenuItemInfo(hMenuOutput, outputItemStart + i, TRUE, &mii);
721                 if (st_temp->opt_playmode[0] == play_mode_list[i]->id_character) {
722                         oldnum = i;
723                 }
724         }
725 //      if (!w32g_play_active && num != oldnum) {
726         if (num != oldnum) {
727                 if (num >= 0) { st_temp->opt_playmode[0] = play_mode_list[num]->id_character; }
728                 else { st_temp->opt_playmode[0] = 'd'; }
729                 w32g_send_rc(RC_STOP, 0);
730                 PrefSettingApplyReally();
731         }
732 }
733
734 static void RefreshOutputMenu(HWND hWnd)
735 {
736         MENUITEMINFOA mii;
737         int i;
738
739         for (i = 0; play_mode_list[i] != 0; i++) {
740                 mii.cbSize = sizeof(MENUITEMINFOA);
741                 mii.fMask = MIIM_STATE | MIIM_ID;
742                 GetMenuItemInfo(hMenuOutput, outputItemStart + i, TRUE, &mii);
743                 if (st_temp->opt_playmode[0] == play_mode_list[i]->id_character) {
744                         mii.fState = MFS_CHECKED;
745                 } else {
746                         mii.fState = MFS_UNCHECKED;
747                 }
748                 SetMenuItemInfo(hMenuOutput, outputItemStart + i, TRUE, &mii);
749         }
750 }
751
752 static void InitMainWnd(HWND hParentWnd)
753 {
754         HICON hIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_TIMIDITY), IMAGE_ICON, 16, 16, 0);
755         if ( hMainWnd != NULL ) {
756                 DestroyWindow ( hMainWnd );
757                 hMainWnd = NULL;
758         }
759         MainWndInfoReset(NULL);
760         INILoadMainWnd();
761         if (PlayerLanguage == LANGUAGE_JAPANESE)
762           hMainWnd = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG_MAIN),hParentWnd,MainProc);
763         else
764           hMainWnd = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG_MAIN_EN),hParentWnd,MainProc);
765         //InithMenuModule(hMainWnd);
766         //InithMenuOutput(hMainWnd);
767
768         if (hIcon!=NULL) SendMessage(hMainWnd,WM_SETICON,FALSE,(LPARAM)hIcon);
769         {  // Set the title of the main window again.
770         char buffer[256];
771         SendMessage( hMainWnd, WM_GETTEXT, (WPARAM)255, (LPARAM)buffer);
772         SendMessage( hMainWnd, WM_SETTEXT, (WPARAM)0, (LPARAM)buffer);
773         }
774         MainWndInfoReset(hMainWnd);
775         INILoadMainWnd();
776         MainWndInfoApply();
777 }
778
779 static int MainWndInfoReset(HWND hwnd)
780 {
781         memset(&MainWndInfo,0,sizeof(MAINWNDINFO));
782         MainWndInfo.PosX = - 1;
783         MainWndInfo.PosY = - 1; 
784         MainWndInfo.Width = - 1;
785         MainWndInfo.Height = - 1;
786         MainWndInfo.hwnd = hwnd;
787         return 0;
788 }
789
790 static int MainWndInfoApply(void)
791 {       
792         RECT d_rc, w_rc;
793
794         GetClientRect ( GetDesktopWindow (), &d_rc );
795         GetWindowRect ( MainWndInfo.hwnd, &w_rc );
796         d_rc.right -= w_rc.right - w_rc.left;
797         d_rc.bottom -= w_rc.bottom - w_rc.top;
798         if ( MainWndInfo.PosX < d_rc.left ) MainWndInfo.PosX = d_rc.left; 
799         if ( MainWndInfo.PosX > d_rc.right ) MainWndInfo.PosX = d_rc.right; 
800         if ( MainWndInfo.PosY < d_rc.top ) MainWndInfo.PosY = d_rc.top; 
801         if ( MainWndInfo.PosY > d_rc.bottom ) MainWndInfo.PosY = d_rc.bottom; 
802         SetWindowPosSize(GetDesktopWindow(), MainWndInfo.hwnd, MainWndInfo.PosX, MainWndInfo.PosY );    
803         if(MainWndInfo.Width <= 0) 
804                 MainWndInfo.Width = 480;
805         if(MainWndInfo.Height <= 0) 
806                 MainWndInfo.Height = 160;
807         MoveWindow(MainWndInfo.hwnd, MainWndInfo.PosX, MainWndInfo.PosY, MainWndInfo.Width, MainWndInfo.Height,TRUE);
808         MainWndInfo.init = 1;
809         return 0;
810 }
811
812 void MainCmdProc(HWND hwnd, int wId, HWND hwndCtl, UINT wNotifyCode);
813
814 void MainWndSetPauseButton(int flag);
815 void MainWndSetPlayButton(int flag);
816
817 void MainWndToggleConsoleButton(void);
818 void MainWndUpdateConsoleButton(void);
819 void MainWndToggleTracerButton(void);
820 void MainWndUpdateTracerButton(void);
821 void MainWndToggleListButton(void);
822 void MainWndUpdateListButton(void);
823 void MainWndToggleDocButton(void);
824 void MainWndUpdateDocButton(void);
825 void MainWndToggleWrdButton(void);
826 void MainWndUpdateWrdButton(void);
827 void MainWndToggleSoundSpecButton(void);
828 void MainWndUpdateSoundSpecButton(void);
829
830 void ShowSubWindow(HWND hwnd,int showflag);
831 void ToggleSubWindow(HWND hwnd);
832
833 static void VersionWnd(HWND hParentWnd);
834 static void TiMidityWnd(HWND hParentWnd);
835 static void SupplementWnd(HWND hParentWnd);
836
837 static void InitCanvasWnd(HWND hwnd);
838 static void CanvasInit(HWND hwnd);
839 static void InitPanelWnd(HWND hwnd);
840 static void MPanelInit(HWND hwnd);
841
842 static void InitMainToolbar(HWND hwnd);
843 static void InitSubWndToolbar(HWND hwnd);
844
845 static UINT PlayerForwardAndBackwardEventID = 0;
846 static void CALLBACK PlayerForward(UINT IDEvent, UINT uReserved, DWORD_PTR dwUser,
847         DWORD_PTR dwReserved1, DWORD_PTR dwReserved2)
848 {
849         w32g_send_rc(RC_FORWARD, play_mode->rate);
850 }
851
852 static void CALLBACK PlayerBackward(UINT IDEvent, UINT uReserved, DWORD_PTR dwUser,
853         DWORD_PTR dwReserved1, DWORD_PTR dwReserved2)
854 {
855         w32g_send_rc(RC_BACK, play_mode->rate);
856 }
857
858 static void CallPrefWnd(UINT_PTR cId);
859 extern void ShowPrefWnd ( void );
860 extern void HidePrefWnd ( void );
861 extern BOOL IsVisiblePrefWnd ( void );
862
863 LRESULT CALLBACK
864 MainProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
865 {
866         static BOOL PrefWndShow;
867
868         // PrintfDebugWnd("MainProc: Mess%lx WPARAM%lx LPARAM%lx\n",uMess,wParam,lParam);
869         switch (uMess)
870         {
871       case WM_INITDIALOG:
872 #ifdef VST_LOADER_ENABLE
873         if (hVSTHost == NULL) {
874 #ifdef _WIN64
875                 hVSTHost = LoadLibrary("timvstwrap_x64.dll");
876 #else
877                 hVSTHost = LoadLibrary("timvstwrap.dll");
878 #endif
879                 if (hVSTHost != NULL) {
880                         ((vst_open)GetProcAddress(hVSTHost, "vstOpen"))();
881         //              ((vst_open_config_all)GetProcAddress(hVSTHost, "openEffectEditorAll"))(hwnd);
882                 }
883         }
884 #endif
885                 PrefWndShow = FALSE;
886                 update_subwindow();
887                 MainWndUpdateConsoleButton();
888                 MainWndUpdateTracerButton();
889                 MainWndUpdateListButton();
890                 MainWndUpdateDocButton();
891                 MainWndUpdateWrdButton();
892                 MainWndUpdateSoundSpecButton();         
893                 InitMainMenu(hwnd); 
894                 InitPanelWnd(hwnd);
895                 InitCanvasWnd(hwnd);
896                 InitMainToolbar(hwnd);
897                 InitSubWndToolbar(hwnd);
898                 {
899                         hMainWndScrollbarVolumeTTipWnd = CreateWindow(TOOLTIPS_CLASS,
900                         NULL, TTS_ALWAYSTIP,
901                         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
902                         hMainWndScrollbarVolumeWnd, NULL, hInst, NULL);
903                         SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_ACTIVATE, (WPARAM)TRUE, 0);
904                         hMainWndScrollbarProgressTTipWnd = CreateWindow(TOOLTIPS_CLASS,
905                         NULL, TTS_ALWAYSTIP,
906                         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
907                         hMainWndScrollbarProgressWnd, NULL, hInst, NULL);
908                         SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_ACTIVATE, (WPARAM)TRUE, 0);
909
910                         SBProgressTooltipInfo.cbSize = sizeof(TOOLINFO);
911                         SBProgressTooltipInfo.uFlags = TTF_SUBCLASS;
912                         SBProgressTooltipInfo.hwnd = hMainWndScrollbarProgressWnd;
913                         SBProgressTooltipInfo.lpszText = SBProgressTooltipText;
914                         GetClientRect(hMainWndScrollbarProgressWnd, &SBProgressTooltipInfo.rect);
915                         SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_ADDTOOL,
916                                 0, (LPARAM)&SBProgressTooltipInfo);
917
918                         SBVolumeTooltipInfo.cbSize = sizeof(TOOLINFO);
919                         SBVolumeTooltipInfo.uFlags = TTF_SUBCLASS;
920                         SBVolumeTooltipInfo.hwnd = hMainWndScrollbarVolumeWnd;
921                         SBVolumeTooltipInfo.lpszText = SBVolumeTooltipText;
922                         GetClientRect(hMainWndScrollbarVolumeWnd, &SBVolumeTooltipInfo.rect);
923                         SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_ADDTOOL,
924                                 0, (LPARAM)&SBVolumeTooltipInfo);
925                 }
926                 return FALSE;
927           HANDLE_MSG(hwnd,WM_COMMAND,MainCmdProc);
928
929           case WM_DESTROY:
930                 {
931                         RECT rc;
932                         WINDOWPLACEMENT wp;
933                         GetWindowRect(hwnd,&rc);
934                         GetWindowPlacement(hwnd, &wp);
935                         if(wp.showCmd == SW_SHOWNORMAL){
936                                 // \8dÅ\8f¬\89»\8fó\91Ô\82È\82Ç\82Å\8fI\97¹\82·\82é\82Æ\90³\8fí\82É\83T\83C\83Y\8eæ\93¾\82Å\82«\82È\82¢ (\83\81\83j\83\85\81[\82ª\8aÜ\82Ü\82ê\82È\82¢\83T\83C\83Y\82É\82È\82é
937                                 MainWndInfo.Width = rc.right - rc.left;
938                                 MainWndInfo.Height = rc.bottom - rc.top;
939                         }
940                 }
941                 if(save_playlist_once_before_exit_flag) {
942                         save_playlist_once_before_exit_flag = 0;
943                         w32gSaveDefaultPlaylist();
944                 }
945                 INISaveMainWnd();
946 #ifdef VST_LOADER_ENABLE
947         if (hVSTHost != NULL) {
948                 // \8dÄ\90\92\86\8fI\97¹\82Ì\8fê\8d\87 \82Ü\82¾\83V\83\93\83Z\82Í\93®\82¢\82Ä\82¢\82é
949                 // vstClose\82Í\8e\9e\8aÔ\82©\82©\82é\82Ì\82Å\90æ\82ÉNULL\82µ\82Ä\82¨\82­
950                 HMODULE htemp = hVSTHost;
951                 hVSTHost = NULL; // VST\8eg\97p\82ð\83u\83\8d\83b\83N
952                 Sleep(100); // 100ms\82à\82 \82ê\82Î\83u\83\8d\83b\83N\91O\82É\8aJ\8en\82µ\82½VST\82Ì\8f\88\97\9d\82Í\8fI\82Á\82Ä\82é\82Í\82¸
953                 ((vst_close)GetProcAddress(htemp,"vstClose"))();
954                 FreeLibrary(htemp);
955         }
956 #endif
957                 PostQuitMessage(0);
958                 break;
959
960           case WM_CLOSE:
961                 if(save_playlist_once_before_exit_flag) {
962                         save_playlist_once_before_exit_flag = 0;
963                         w32gSaveDefaultPlaylist();
964                 }
965                 DestroyWindow(hwnd);
966                 break;
967                 
968         case WM_GETMINMAXINFO:
969                 {
970                         LPMINMAXINFO lpmmi = (LPMINMAXINFO) lParam;
971                         lpmmi->ptMinTrackSize.x = max(345, lpmmi->ptMinTrackSize.x); // full:475
972                         lpmmi->ptMinTrackSize.y = max(158, lpmmi->ptMinTrackSize.y);
973                 //      lpmmi->ptMaxTrackSize.y = 158;
974                 }
975                 return 0;
976       case WM_SIZE:
977                 switch(wParam){
978                 case SIZE_RESTORED:
979                         if ( PrefWndShow ) {
980                                 ShowPrefWnd ();
981                         }
982                         if(MainWndInfo.init){
983                                 RECT rc;
984                                 GetWindowRect(hwnd,&rc);
985                                 MainWndInfo.Width = rc.right - rc.left;
986                                 MainWndInfo.Height = rc.bottom - rc.top;
987                         }
988                         break;
989                 case SIZE_MINIMIZED:
990                         if ( IsVisiblePrefWnd () )
991                                 PrefWndShow = TRUE;
992                         else
993                                 PrefWndShow = FALSE;
994                         HidePrefWnd ();
995                         update_subwindow();
996                         OnHide();
997                         break;
998                 default:
999                         break;
1000                 }
1001                 return FALSE;
1002           case WM_MOVE:
1003                 if ( ! IsIconic(hwnd) ) {
1004                         RECT rc;
1005                         GetWindowRect(hwnd,&rc);
1006                         MainWndInfo.PosX = rc.left;
1007                         MainWndInfo.PosY = rc.top;
1008                 }
1009                 break;
1010       case WM_QUERYOPEN:
1011                 OnShow();
1012                 return FALSE;
1013       case WM_DROPFILES:
1014 #ifdef EXT_CONTROL_MAIN_THREAD
1015                 w32g_ext_control_main_thread(RC_EXT_DROP, (ptr_size_t)wParam);
1016 #else
1017                 w32g_send_rc(RC_EXT_DROP, (ptr_size_t)wParam);
1018 #endif
1019                 return FALSE;
1020       case WM_HSCROLL: {
1021                 int nScrollCode = (int)LOWORD(wParam);
1022                 int nPos = (int) HIWORD(wParam);
1023                 HWND bar = (HWND)lParam;
1024
1025                 if(bar != hMainWndScrollbarProgressWnd)
1026                         break;
1027
1028                 switch(nScrollCode)     {
1029                 case SB_THUMBTRACK:
1030                 case SB_THUMBPOSITION:
1031                         progress_jump = nPos;
1032                         break;
1033                 case SB_LINELEFT:
1034                         progress_jump = GetScrollPos(bar, SB_CTL) - 1;
1035                         if(progress_jump < 0)
1036                                 progress_jump = 0;
1037                         SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, progress_jump, TRUE);
1038                         break;
1039                 case SB_PAGELEFT:
1040                         progress_jump = GetScrollPos(bar, SB_CTL) - 10;
1041                         if(progress_jump < 0)
1042                                 progress_jump = 0;
1043                         SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, progress_jump, TRUE);
1044                         break;
1045                 case SB_LINERIGHT:
1046                         progress_jump = GetScrollPos(bar, SB_CTL) + 1;
1047                         SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, progress_jump, TRUE);
1048                         break;
1049                 case SB_PAGERIGHT:
1050                         progress_jump = GetScrollPos(bar, SB_CTL) + 10;
1051                         SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, progress_jump, TRUE);
1052                         break;
1053                 case SB_ENDSCROLL:
1054                         if(progress_jump != -1)
1055                         {
1056                                 w32g_send_rc(RC_JUMP, progress_jump * play_mode->rate);
1057                                 SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, progress_jump, TRUE);
1058                                 progress_jump = -1;
1059
1060                         SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_TRACKACTIVATE,
1061                                 FALSE, (LPARAM)&SBProgressTooltipInfo);
1062                         SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_ACTIVATE,
1063                                 (WPARAM)FALSE, 0);
1064                         }
1065                         break;
1066             }
1067
1068             if (nScrollCode != SB_ENDSCROLL && progress_jump != -1)
1069             {
1070                 POINT point = { 0, 0 };
1071                 uint32 CurTime_h, CurTime_m, CurTime_s;
1072                 uint32 TotalTime_h, TotalTime_m, TotalTime_s;
1073
1074                 CurTime_s = progress_jump;
1075                 CurTime_m = CurTime_s / 60;
1076                 CurTime_s %= 60;
1077                 CurTime_h = CurTime_m / 60;
1078                 CurTime_m %= 60;
1079
1080                 TotalTime_s = 0;
1081                 GetScrollRange(hMainWndScrollbarProgressWnd, SB_CTL, &TotalTime_m, &TotalTime_s);
1082                 TotalTime_m = TotalTime_s / 60;
1083                 TotalTime_s %= 60;
1084                 TotalTime_h = TotalTime_m / 60;
1085                 TotalTime_m %= 60;
1086
1087                 wsprintf(SBProgressTooltipText, TEXT("%02u:%02u:%02u/%02u:%02u:%02u\0"),
1088                                                 CurTime_h, CurTime_m, CurTime_s,
1089                                                 TotalTime_h, TotalTime_m, TotalTime_s);
1090                 SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_UPDATETIPTEXT,
1091                             0, (LPARAM)&SBProgressTooltipInfo);
1092
1093                 ClientToScreen(hMainWndScrollbarProgressWnd, &point);
1094                 SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_TRACKPOSITION,
1095                             0, MAKELPARAM(point.x, point.y));
1096
1097                 SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_ACTIVATE,
1098                             (WPARAM)TRUE, 0);
1099                 SendMessage(hMainWndScrollbarProgressTTipWnd, TTM_TRACKACTIVATE,
1100                             TRUE, (LPARAM)&SBProgressTooltipInfo);
1101             }
1102             break;
1103           }
1104           break;
1105           case WM_VSCROLL: {
1106                 int nScrollCode = (int) LOWORD(wParam);
1107                 int nPos = (int) HIWORD(wParam);
1108                 HWND bar = (HWND) lParam;
1109                 static int pos = -1;
1110
1111                 if(bar != hMainWndScrollbarVolumeWnd)
1112                         break;
1113                 switch(nScrollCode)
1114                 {
1115                         case SB_THUMBTRACK:
1116                         case SB_THUMBPOSITION:
1117                         pos = nPos;
1118                         break;
1119                         case SB_LINEUP:
1120                         case SB_PAGEUP:
1121                         pos = GetScrollPos(bar, SB_CTL) - (nScrollCode == SB_LINEUP ? 5 : 20);
1122                         if(pos < 0)
1123                                 pos = 0;
1124                         SetScrollPos(bar, SB_CTL, pos, TRUE);
1125                         break;
1126                         case SB_LINEDOWN:
1127                         case SB_PAGEDOWN:
1128                         pos = GetScrollPos(bar, SB_CTL) + (nScrollCode == SB_LINEDOWN ? 5 : 20);
1129                         if(pos > W32G_VOLUME_MAX)
1130                                 pos = W32G_VOLUME_MAX;
1131                         SetScrollPos(bar, SB_CTL, pos, TRUE);
1132                         break;
1133                         case SB_ENDSCROLL:
1134                         if(pos != -1)
1135                         {
1136                                 w32g_send_rc(RC_CHANGE_VOLUME,
1137                                                                 (W32G_VOLUME_MAX - pos) - output_amplification);
1138                                 SetScrollPos(bar, SB_CTL, pos, TRUE);
1139                                 pos = -1;
1140
1141                                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_TRACKACTIVATE,
1142                                         FALSE, (LPARAM)&SBVolumeTooltipInfo);
1143                                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_ACTIVATE,
1144                                         (WPARAM)FALSE, 0);
1145                         }
1146                         break;
1147             }
1148
1149             if (nScrollCode != SB_ENDSCROLL && pos != -1)
1150             {
1151                 POINT point = { 0, 0 };
1152
1153                 wsprintf(SBVolumeTooltipText, TEXT("%u %%\0"), W32G_VOLUME_MAX - pos);
1154                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_UPDATETIPTEXT,
1155                             0, (LPARAM)&SBVolumeTooltipInfo);
1156
1157                 ClientToScreen(hMainWndScrollbarVolumeWnd, &point);
1158                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_TRACKPOSITION,
1159                             0, MAKELPARAM(point.x, point.y));
1160
1161                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_ACTIVATE,
1162                             (WPARAM)TRUE, 0);
1163                 SendMessage(hMainWndScrollbarVolumeTTipWnd, TTM_TRACKACTIVATE,
1164                             TRUE, (LPARAM)&SBVolumeTooltipInfo);
1165             }
1166           }
1167           break;
1168       case WM_MOUSEWHEEL:
1169       {
1170                 static int16 wheel_delta = 0;
1171                 int16 wheel_speed;
1172                 int pos;
1173
1174                 wheel_delta += (int16)GET_WHEEL_DELTA_WPARAM(wParam);
1175                 wheel_speed = wheel_delta / WHEEL_DELTA; // upper 16bit sined int // 1knoch = 120
1176                 wheel_delta %= WHEEL_DELTA;
1177                 pos = GetScrollPos(hMainWndScrollbarVolumeWnd, SB_CTL) - wheel_speed;
1178                 if(pos < 0)
1179                         pos = 0;
1180                 if(pos > W32G_VOLUME_MAX)
1181                         pos = W32G_VOLUME_MAX;
1182                 w32g_send_rc(RC_CHANGE_VOLUME,
1183                                                 (W32G_VOLUME_MAX - pos) - output_amplification);
1184                 SetScrollPos(hMainWndScrollbarVolumeWnd, SB_CTL, pos, TRUE);
1185                 break;
1186       }
1187           case WM_SYSCOMMAND:
1188                 switch(wParam){
1189                   case IDM_STOP:
1190                   case IDM_PAUSE:
1191                   case IDM_PREV:
1192                   case IDM_PLAY:
1193                   case IDM_NEXT:
1194                   case IDM_FOREWARD:
1195                   case IDM_BACKWARD:
1196                         SendMessage(hwnd,WM_COMMAND,wParam,(LPARAM)NULL);
1197                         break;
1198                   default:
1199                         break;
1200                 }
1201                 return FALSE;
1202       case WM_NOTIFY:
1203                 switch(wParam) {
1204                   case IDC_TOOLBARWINDOW_MAIN:{
1205                           LPTBNOTIFY TbNotify = (LPTBNOTIFY)lParam;
1206                           switch(TbNotify->iItem){
1207                                 case IDM_BACKWARD:
1208                                   if(TbNotify->hdr.code==TBN_BEGINDRAG){
1209 #ifdef W32GUI_DEBUG
1210                                           //PrintfDebugWnd("IDM_BACKWARD: BUTTON ON\n");
1211 #endif
1212                                           PlayerBackward(0,0,0,0,0);
1213                                           PlayerForwardAndBackwardEventID =
1214                                                   timeSetEvent(100, 100, PlayerBackward, 0, TIME_PERIODIC);
1215                                   }
1216                                   if(PlayerForwardAndBackwardEventID != 0)
1217                                           if(TbNotify->hdr.code==TBN_ENDDRAG){
1218 #ifdef W32GUI_DEBUG
1219                                                   //PrintfDebugWnd("IDM_BACKWARD: BUTTON OFF\n");
1220 #endif
1221                                                   timeKillEvent(PlayerForwardAndBackwardEventID);
1222                                                   PlayerForwardAndBackwardEventID = 0;
1223                                           }
1224                                   break;
1225                                 case IDM_FOREWARD:
1226                                   if(TbNotify->hdr.code ==TBN_BEGINDRAG &&
1227                                          PlayerForwardAndBackwardEventID == 0){
1228 #ifdef W32GUI_DEBUG
1229                                           //PrintfDebugWnd("IDM_FOREWARD: BUTTON ON\n");
1230 #endif
1231                                           PlayerForward(0,0,0,0,0);
1232                                           PlayerForwardAndBackwardEventID =
1233                                                   timeSetEvent(100,300,PlayerForward,0,TIME_PERIODIC);
1234                                   }
1235                                   else if((TbNotify->hdr.code == TBN_ENDDRAG ||
1236                                                    TbNotify->hdr.code == NM_CLICK ||
1237                                                    TbNotify->hdr.code == NM_RCLICK) &&
1238                                                   PlayerForwardAndBackwardEventID != 0)
1239                                   {
1240 #ifdef W32GUI_DEBUG
1241                                           //PrintfDebugWnd("IDM_FOREWARD: BUTTON OFF\n");
1242 #endif
1243                                           timeKillEvent(PlayerForwardAndBackwardEventID);
1244                                           PlayerForwardAndBackwardEventID = 0;
1245                                   }
1246                                   break;
1247                                 default:
1248                                   break;
1249                           }
1250                     }
1251                         break; /* end of case IDC_TOOLBARWINDOW_MAIN */
1252                   default:
1253                         break;
1254                 }
1255                 return FALSE;
1256         case WM_SHOWWINDOW:
1257         {
1258                 BOOL fShow = (BOOL)wParam;
1259                 if ( fShow ) {
1260                         if ( PrefWndShow ) {
1261                                 ShowPrefWnd ();
1262                         } else {
1263                                 HidePrefWnd ();
1264                         }
1265                 } else {
1266                         if ( IsVisiblePrefWnd () )
1267                                 PrefWndShow = TRUE;
1268                         else
1269                                 PrefWndShow = FALSE;
1270                         HidePrefWnd ();
1271                 }
1272                 break;
1273         }
1274                 break;
1275       default:
1276                 if (uMess == RegisterWindowMessage("TaskbarCreated")) {
1277                         ShowWindow(hMainWnd, SW_HIDE);
1278                         ShowWindow(hMainWnd, SW_SHOWNOACTIVATE);
1279                         return 0;
1280                 }
1281                 return FALSE;
1282     }
1283         return FALSE;
1284 }
1285
1286 extern int TracerWndDrawSkip;
1287 void PrefWndCreate(HWND hwnd, UINT cid);
1288
1289 void MainCmdProc(HWND hwnd, int wId, HWND hwndCtl, UINT wNotifyCode)
1290 {
1291          // PrintfDebugWnd("WM_COMMAND: ID%lx HWND%lx CODE%lx\n",wId,hwndCtl,wNotifyCode);
1292     switch(wId)
1293     {
1294       case IDM_STOP:
1295                         TracerWndDrawSkip = 1;
1296                   w32g_send_rc(RC_STOP, 0);
1297                   break;
1298       case IDM_PAUSE:
1299                         TracerWndDrawSkip = !TracerWndDrawSkip;
1300                   SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_MAIN,
1301                                                                         TB_CHECKBUTTON, IDM_PAUSE,
1302                                                                         (LPARAM)MAKELONG(!play_pause_flag, 0));
1303                   w32g_send_rc(RC_TOGGLE_PAUSE, 0);
1304                   break;
1305       case IDM_PREV:
1306                         TracerWndDrawSkip = 1;
1307                   w32g_send_rc(RC_REALLY_PREVIOUS, 0);
1308                   break;
1309       case IDM_BACKWARD:
1310                   /* Do nothing here. See WM_NOTIFY in MainProc() */
1311                   break;
1312       case IDM_PLAY:
1313                         TracerWndDrawSkip = 0;
1314                   if(play_pause_flag)
1315                   {
1316                                 SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_MAIN,
1317                                                                                  TB_CHECKBUTTON, IDM_PAUSE,
1318                                                                                  (LPARAM)MAKELONG(FALSE, 0));
1319                                 w32g_send_rc(RC_TOGGLE_PAUSE, 0);
1320                   }
1321                   if(!w32g_play_active)
1322                                 w32g_send_rc(RC_LOAD_FILE, 0);
1323                   break;
1324       case IDM_FOREWARD:
1325                   /* Do nothing here. See WM_NOTIFY in MainProc() */
1326                   break;
1327       case IDM_NEXT:
1328                         TracerWndDrawSkip = 1;
1329                   w32g_send_rc(RC_NEXT, 0);
1330                   break;
1331       case IDM_CONSOLE:
1332       case IDM_MWCONSOLE:
1333                   ToggleSubWindow(hConsoleWnd);
1334                   break;
1335       case IDM_TRACER:
1336       case IDM_MWTRACER:
1337                   ToggleSubWindow(hTracerWnd);
1338 //                MainWndUpdateTracerButton();
1339 //                MessageBox(hwnd, "Not Supported.","Warning!",MB_OK);
1340                   break;
1341       case IDM_LIST:
1342       case IDM_MWPLAYLIST:
1343                   ToggleSubWindow(hListWnd);
1344                   if(IsWindowVisible(hListWnd))
1345 #ifdef EXT_CONTROL_MAIN_THREAD
1346                         w32g_ext_control_main_thread(RC_EXT_UPDATE_PLAYLIST, 0);
1347 #else
1348                         w32g_send_rc(RC_EXT_UPDATE_PLAYLIST, 0);
1349 #endif
1350                   break;
1351       case IDM_DOC:
1352       case IDM_MWDOCUMENT:
1353                   ToggleSubWindow(hDocWnd);
1354 //                if(IsWindowVisible(hDocWnd))
1355 //                        w32g_send_rc(RC_EXT_DOC, 0);
1356                   break;
1357       case IDM_WRD:
1358       case IDM_MWWRDTRACER:
1359                   ToggleSubWindow(hWrdWnd);
1360 //                MainWndUpdateWrdButton();
1361 //                MessageBox(hwnd, "Not Supported.","Warning!",MB_OK);
1362                   break;
1363       case IDM_SOUNDSPEC:
1364       case IDM_MWSOUNDSPEC:
1365                   ToggleSubWindow(hSoundSpecWnd);
1366 //                MainWndUpdateSoundSpecButton();
1367 //                MessageBox(hwnd, "Not Supported.","Warning!",MB_OK);
1368                   break;
1369 ///r
1370       case IDM_VSTMGR:
1371       case IDM_MWVSTMGR:
1372 #ifdef VST_LOADER_ENABLE
1373         if (!hVSTHost) {
1374             w32_reset_dll_directory();
1375 #ifdef _WIN64
1376             hVSTHost = LoadLibrary(TEXT("timvstwrap_x64.dll"));
1377 #else
1378             hVSTHost = LoadLibrary(TEXT("timvstwrap.dll"));
1379 #endif
1380             if (hVSTHost && GetProcAddress(hVSTHost, "vstOpen")) {
1381                 ((vst_open) GetProcAddress(hVSTHost, "vstOpen"))();
1382             }
1383         }
1384
1385         if (hVSTHost) {
1386             ((open_vst_mgr) GetProcAddress(hVSTHost, "openVSTManager"))(hwnd);
1387         }
1388         else if (hVSTHost) {
1389 #ifdef _WIN64
1390             const TCHAR *vst_nosupport,
1391                          vst_nosupport_en[] = TEXT("openVSTManager could not be found in timvstwrap_x64.dll"),
1392                          vst_nosupport_jp[] = TEXT("openVSTManager \82ª timvstwrap_x64.dll \82©\82ç\8c©\82Â\82©\82è\82Ü\82¹\82ñ\82Å\82µ\82½\81B");
1393 #else
1394             const TCHAR *vst_nosupport,
1395                          vst_nosupport_en[] = TEXT("openVSTManager could not be found in timvstwrap.dll"),
1396                          vst_nosupport_jp[] = TEXT("openVSTManager \82ª timvstwrap.dll \82©\82ç\8c©\82Â\82©\82è\82Ü\82¹\82ñ\82Å\82µ\82½\81B");
1397 #endif
1398             if (PlayerLanguage == LANGUAGE_JAPANESE)
1399                 vst_nosupport = vst_nosupport_jp;
1400             else
1401                 vst_nosupport = vst_nosupport_en;
1402             MessageBox(hwnd, vst_nosupport, TEXT("TiMidity Warning"), MB_OK | MB_ICONWARNING);
1403         }
1404         else {
1405 #ifdef _WIN64
1406             const TCHAR *vst_nosupport,
1407                          vst_nosupport_en[] = TEXT("Cannot load timvstwrap_x64.dll"),
1408                          vst_nosupport_jp[] = TEXT("timvstwrap_x64.dll \82ð\83\8d\81[\83h\82µ\82Ä\82¢\82Ü\82¹\82ñ\81B");
1409 #else
1410             const TCHAR *vst_nosupport,
1411                          vst_nosupport_en[] = TEXT("Cannot load timvstwrap.dll"),
1412                          vst_nosupport_jp[] = TEXT("timvstwrap.dll \82ð\83\8d\81[\83h\82µ\82Ä\82¢\82Ü\82¹\82ñ\81B");
1413 #endif
1414             if (PlayerLanguage == LANGUAGE_JAPANESE)
1415                 vst_nosupport = vst_nosupport_jp;
1416             else
1417                 vst_nosupport = vst_nosupport_en;
1418             MessageBox(hwnd, vst_nosupport, TEXT("TiMidity Warning"), MB_OK | MB_ICONWARNING);
1419         }
1420 #endif
1421                   break;
1422           case IDM_MWISEDITOR:
1423 #ifdef INT_SYNTH
1424                   ISEditorWndCreate(hwnd);      
1425 #endif
1426                   break;
1427       case IDOK:
1428                   break;
1429       case IDCANCEL:
1430                   OnQuit();
1431                   break;
1432       case IDM_MFOPENFILE:
1433                   DlgMidiFileOpen(hwnd);
1434                   break;
1435       case IDM_MFOPENDIR:
1436                   DlgDirOpen(hwnd);
1437                   break;
1438       case IDM_MFOPENURL:
1439                   DlgUrlOpen(hwnd);
1440                   break;
1441       case IDM_MFLOADPLAYLIST:
1442                   DlgPlaylistOpen(hwnd);
1443                   break;
1444       case IDM_MFSAVEPLAYLISTAS:
1445                   DlgPlaylistSave(hwnd);
1446                   break;
1447       case IDM_MFRESTART:
1448                   RestartTimidity = 1; // WinMain()
1449                   // thru exit
1450       case IDM_MFEXIT:
1451                   OnQuit();
1452                   break;
1453
1454       case IDM_SETTING:
1455                   CallPrefWnd(0);
1456                   break;
1457
1458       case IDM_MCSAVEINIFILE:
1459                   VOLATILE_TOUCH(PrefWndDoing);
1460                   if(PrefWndDoing){
1461                                 MessageBox(hMainWnd, "Can't Save Ini file while preference dialog.",
1462                                                           "Warning", MB_OK);
1463                                 break;
1464                   }
1465                   SaveIniFile(sp_current, st_current);
1466                   break;
1467       case IDM_MCLOADINIFILE:
1468                  if(!w32g_has_ini_file) {
1469                      MessageBox(hMainWnd, "Can't load Ini file.",
1470                                 "Warning", MB_OK);
1471                      break;
1472                  }
1473
1474                   VOLATILE_TOUCH(PrefWndDoing);
1475                   if(PrefWndDoing){
1476                                 MessageBox(hMainWnd, "Can't load Ini file while preference dialog.",
1477                                                           "Warning", MB_OK);
1478                                 break;
1479                   }
1480                   LoadIniFile(sp_temp,st_temp);
1481                   CallPrefWnd(0);
1482                   break;
1483       case IDM_MWDEBUG:
1484 #ifdef W32GUI_DEBUG
1485                   if(IsWindowVisible(hDebugWnd))
1486                                 ShowWindow(hDebugWnd,SW_HIDE);
1487                   else
1488                                 ShowWindow(hDebugWnd,SW_SHOW);
1489 #endif
1490                   break;
1491       case IDM_MHTOPIC:
1492                   MessageBox(hwnd, "Not Supported.","Warning!",MB_OK);
1493                   break;
1494       case IDM_MHHELP:
1495                   MessageBox(hwnd, "Not Supported.","Warning!",MB_OK);
1496                   break;
1497       case IDM_MHONLINEHELP:
1498                   if (PlayerLanguage == LANGUAGE_JAPANESE) {
1499                           ShellExecute(HWND_DESKTOP, NULL, "http://timidity-docs.sourceforge.jp/", NULL, NULL, SW_SHOWNORMAL);
1500                   } else {
1501                           ShellExecute(HWND_DESKTOP, NULL, "http://timidity.sourceforge.net/index.html.en", NULL, NULL, SW_SHOWNORMAL);
1502                   }
1503                   break;
1504       case IDM_MHBTS:
1505                   if (PlayerLanguage == LANGUAGE_JAPANESE) {
1506                           ShellExecute(HWND_DESKTOP, NULL, "http://timidity-docs.sourceforge.jp/cgi-bin/kagemai-ja/guest.cgi", NULL, NULL, SW_SHOWNORMAL);
1507                   } else {
1508                           ShellExecute(HWND_DESKTOP, NULL, "http://timidity-docs.sourceforge.jp/cgi-bin/kagemai-en/guest.cgi", NULL, NULL, SW_SHOWNORMAL);
1509                   }
1510                   break;
1511       case IDM_MHONLINEHELPCFG:
1512                   ShellExecute(HWND_DESKTOP, NULL, "http://timidity-docs.sourceforge.jp/cgi-bin/hiki/hiki.cgi?%28ja%29timidity.cfg", NULL, NULL, SW_SHOWNORMAL);
1513                   break;
1514       case IDM_MHVERSION:
1515                   VersionWnd(hwnd);
1516                   break;
1517       case IDM_MHTIMIDITY:
1518                   TiMidityWnd(hwnd);
1519                   break;
1520       case IDM_FORCE_RELOAD:
1521                   if (!w32g_play_active) {reload_cfg();}
1522                   break;
1523       case IDM_MHSUPPLEMENT:
1524                   SupplementWnd(hwnd);
1525                   break;
1526           default:
1527 ///r
1528         // sort large ID
1529         if (IDM_MODULE <= wId)
1530             UpdateModuleMenu(hwnd, wId);
1531         else if (IDM_OUTPUT_OPTIONS == wId) {
1532             UINT id;
1533             if (PlayerLanguage == LANGUAGE_JAPANESE) {
1534                 id = IDD_PREF_TIMIDITY3;
1535             }
1536             else {
1537                 id = IDD_PREF_TIMIDITY3_EN;
1538             }
1539             CallPrefWnd(id);
1540         }
1541         else if (IDM_OUTPUT <= wId)
1542             UpdateOutputMenu(hwnd, wId);
1543         break;
1544     }
1545 }
1546
1547 static void CallPrefWnd(UINT_PTR cId)
1548 {
1549     PrefWndCreate(hMainWnd, cId);
1550
1551     MPanelReadPanelInfo(1);
1552     MPanelUpdateAll();
1553     MPanelPaintAll();
1554
1555     SetScrollPos(hMainWndScrollbarVolumeWnd, SB_CTL,
1556                  W32G_VOLUME_MAX - output_amplification, TRUE);
1557
1558     RefreshOutputMenu(hMainWnd);
1559 }
1560
1561
1562 void update_subwindow(void)
1563 {
1564   SUBWINDOW *s = subwindow;
1565   int i;
1566   for(i=0;s[i].hwnd!=NULL;i++){
1567                 if(IsWindow(*(s[i].hwnd)))
1568                 s[i].status |= SWS_EXIST;
1569                 else {
1570                 s[i].status = 0;
1571         continue;
1572     }
1573                 if(IsIconic(*(s[i].hwnd)))
1574                 s[i].status |= SWS_ICON;
1575                 else
1576                 s[i].status &= ~ SWS_ICON;
1577                 if(IsWindowVisible(*(s[i].hwnd)))
1578                 s[i].status &= ~ SWS_HIDE;
1579                 else
1580                 s[i].status |= SWS_HIDE;
1581         }
1582 }
1583
1584 void MainWndSetPauseButton(int flag)
1585 {
1586         if(flag)
1587         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_MAIN,
1588         TB_CHECKBUTTON, IDM_PAUSE, (LPARAM)MAKELONG(TRUE, 0));
1589         else
1590         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_MAIN,
1591         TB_CHECKBUTTON, IDM_PAUSE, (LPARAM)MAKELONG(FALSE, 0));
1592 }
1593
1594 void MainWndSetPlayButton(int flag)
1595 {
1596         return;
1597 }
1598
1599 void MainWndUpdateConsoleButton(void)
1600 {
1601         if(IsWindowVisible(hConsoleWnd))
1602         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1603         TB_CHECKBUTTON, IDM_CONSOLE, (LPARAM)MAKELONG(TRUE, 0));
1604         else
1605         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1606         TB_CHECKBUTTON, IDM_CONSOLE, (LPARAM)MAKELONG(FALSE, 0));
1607 }
1608
1609 void MainWndUpdateListButton(void)
1610 {
1611         if(IsWindowVisible(hListWnd))
1612         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1613         TB_CHECKBUTTON, IDM_LIST, (LPARAM)MAKELONG(TRUE, 0));
1614         else
1615         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1616         TB_CHECKBUTTON, IDM_LIST, (LPARAM)MAKELONG(FALSE, 0));
1617 }
1618
1619 void MainWndUpdateDocButton(void)
1620 {
1621         if(IsWindowVisible(hDocWnd))
1622         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1623         TB_CHECKBUTTON, IDM_DOC, (LPARAM)MAKELONG(TRUE, 0));
1624         else
1625         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1626         TB_CHECKBUTTON, IDM_DOC, (LPARAM)MAKELONG(FALSE, 0));
1627 }
1628
1629 void MainWndUpdateTracerButton(void)
1630 {
1631         if(IsWindowVisible(hTracerWnd))
1632                 SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1633                         TB_CHECKBUTTON, IDM_TRACER,
1634                         (LPARAM)MAKELONG(TRUE, 0));
1635    else
1636                 SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1637                         TB_CHECKBUTTON, IDM_TRACER,
1638                         (LPARAM)MAKELONG(FALSE, 0));
1639 }
1640
1641 void MainWndUpdateWrdButton(void)
1642 {
1643         if(IsWindowVisible(hWrdWnd))
1644         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1645         TB_CHECKBUTTON, IDM_WRD, (LPARAM)MAKELONG(TRUE, 0));
1646         else
1647         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1648         TB_CHECKBUTTON, IDM_WRD, (LPARAM)MAKELONG(FALSE, 0));
1649 }
1650
1651
1652 void MainWndUpdateSoundSpecButton(void)
1653 {
1654         if(IsWindowVisible(hSoundSpecWnd))
1655                 SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1656                         TB_CHECKBUTTON, IDM_SOUNDSPEC,
1657                         (LPARAM)MAKELONG(TRUE, 0));
1658         else
1659                 SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
1660                         TB_CHECKBUTTON, IDM_SOUNDSPEC,
1661                         (LPARAM)MAKELONG(FALSE, 0));
1662 }
1663
1664 #undef SUBWINDOW_POS_IS_OLD_CLOSED_WINDOW
1665 void ShowSubWindow(HWND hwnd,int showflag)
1666 {
1667         int i, num;
1668         RECT rc;
1669 #ifdef SUBWINDOW_POS_IS_OLD_CLOSED_WINDOW
1670         RECT rc2;
1671 #endif
1672         int max = 0;
1673         if(showflag){
1674                 if(IsWindowVisible(hwnd))
1675                 return;
1676                 for(i=0;SubWindowHistory[i].hwnd!=NULL;i++)
1677                 if(*(SubWindowHistory[i].hwnd)==hwnd)
1678         num = i;
1679                 for(i=0;SubWindowHistory[i].hwnd!=NULL;i++)
1680                 if(*(SubWindowHistory[i].hwnd)!=hwnd){
1681                         if(SubWindowHistory[i].status > 0)
1682                                         SubWindowHistory[i].status += 1;
1683                         if(SubWindowHistory[i].status>SubWindowMax){
1684                                         if(SubWindowHistory[i].status>max){
1685                                 GetWindowRect(*(SubWindowHistory[i].hwnd), &rc);
1686                                                 max = SubWindowHistory[i].status;
1687                                         }
1688                 ShowWindow(*(SubWindowHistory[i].hwnd),SW_HIDE);
1689                                         SubWindowHistory[i].status = 0;
1690                                 }
1691                         }
1692 #ifdef SUBWINDOW_POS_IS_OLD_CLOSED_WINDOW
1693                 // \83T\83u\83E\83C\83\93\83h\83E\82ð\8dÅ\91å\90\94\82ð\89z\82¦\82Ä\95Â\82\82ç\82ê\82é\8cÃ\82¢\83E\83C\83\93\83h\83E\82É\8d\87\82í\82¹\82é\8ed\97l\82Í\8e~\82ß\82é\82±\82Æ\82É\82µ\82½\81B
1694                 if(max>0){
1695                         GetWindowRect(hwnd, &rc2);
1696                         MoveWindow(hwnd,rc.left,rc.top,rc2.right-rc2.left,rc2.bottom-rc2.top,TRUE);
1697                 }
1698 #endif
1699                 ShowWindow(hwnd,SW_SHOW);
1700                 SubWindowHistory[num].status = 1;
1701         } else {
1702                 if(!IsWindowVisible(hwnd))
1703                 return;
1704                 for(i=0;SubWindowHistory[i].hwnd!=NULL;i++)
1705                 if(*(SubWindowHistory[i].hwnd)==hwnd)
1706         num = i;
1707                 for(i=0;SubWindowHistory[i].hwnd!=NULL;i++)
1708         if(i!=num)
1709                         if(SubWindowHistory[i].status>=SubWindowHistory[num].status)
1710                                         SubWindowHistory[i].status -= 1;
1711     ShowWindow(hwnd,SW_HIDE);
1712                 SubWindowHistory[num].status = 0;
1713         }
1714         MainWndUpdateConsoleButton();
1715         MainWndUpdateListButton();
1716         MainWndUpdateTracerButton();
1717         MainWndUpdateDocButton();
1718         MainWndUpdateWrdButton();
1719         MainWndUpdateSoundSpecButton();
1720 }
1721
1722 void ToggleSubWindow(HWND hwnd)
1723 {
1724         if(IsWindowVisible(hwnd))
1725                 ShowSubWindow(hwnd,0);
1726   else
1727                 ShowSubWindow(hwnd,1);
1728 }
1729
1730 void OnShow(void)
1731 {
1732   SUBWINDOW *s = subwindow;
1733         int i;
1734   for(i=0;s[i].hwnd!=NULL;i++)
1735                 if(s[i].status & SWS_EXIST) {
1736                         if(s[i].status & SWS_HIDE)
1737                 ShowWindow(*(s[i].hwnd),SW_HIDE);
1738                         else
1739                 ShowWindow(*(s[i].hwnd),SW_SHOW);
1740                 }
1741 }
1742
1743 void OnHide(void)
1744 {
1745   SUBWINDOW *s = subwindow;
1746         int i;
1747   for(i=0;s[i].hwnd!=NULL;i++){
1748                 if(s[i].status & SWS_EXIST)
1749         ShowWindow(*(s[i].hwnd),SW_HIDE);
1750   }
1751 }
1752
1753 #ifdef W32GUI_DEBUG
1754 void WINAPI DebugThread(void *args)
1755 {
1756         MSG msg;
1757         DebugThreadExit = 0;
1758 //      InitDebugWnd(NULL);
1759         ShowWindow(hDebugWnd,SW_SHOW);
1760         AttachThreadInput(GetWindowThreadProcessId(hDebugThread,NULL),
1761         GetWindowThreadProcessId(hWindowThread,NULL),TRUE);
1762         AttachThreadInput(GetWindowThreadProcessId(hWindowThread,NULL),
1763         GetWindowThreadProcessId(hDebugThread,NULL),TRUE);
1764         while( GetMessage(&msg,NULL,0,0) ){
1765                 TranslateMessage(&msg);
1766                 DispatchMessage(&msg);
1767         }
1768         DebugThreadExit = 1;
1769         crt_endthread();
1770 }
1771
1772 void DebugThreadInit(void)
1773 {
1774         DWORD dwThreadID;
1775         if(!DebugThreadExit)
1776         return;
1777         hDebugThread = crt_beginthreadex(NULL,0,(LPTHREAD_START_ROUTINE)DebugThread,0,0,&dwThreadID);   
1778 }
1779 #endif
1780
1781
1782
1783
1784
1785 //-----------------------------------------------------------------------------
1786 // Toolbar Main
1787
1788 static TBBUTTON MainTbb[] = {
1789     {4, IDM_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
1790     {3, IDM_PAUSE, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0},
1791     {0, IDM_PREV, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
1792     {1, IDM_BACKWARD, TBSTATE_ENABLED,TBSTYLE_BUTTON, 0, 0},
1793     {2, IDM_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
1794     {5, IDM_FOREWARD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
1795     {6, IDM_NEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0}
1796 };
1797
1798 static void InitMainToolbar(HWND hwnd)
1799 {
1800         TBADDBITMAP MainTbab;
1801   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_MAIN,
1802                 TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
1803   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_MAIN,
1804                 TB_SETBUTTONSIZE, (WPARAM)0, (LPARAM)MAKELONG(16,16));
1805         MainTbab.hInst = hInst;
1806         MainTbab.nID =(int)IDB_BITMAP_MAIN_BUTTON;
1807   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_MAIN,
1808         TB_ADDBITMAP, 7, (LPARAM)&MainTbab);
1809   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_MAIN,
1810         TB_ADDBUTTONS, (WPARAM)7,(LPARAM)&MainTbb);
1811   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_MAIN,
1812                 TB_AUTOSIZE, 0, 0);
1813 }
1814
1815 //-----------------------------------------------------------------------------
1816 // Toolbar SubWnd
1817
1818 #define SUBWNDTOOLBAR_BITMAPITEMS 7
1819 static TBBUTTON SubWndTbb[] = {
1820     { 3, IDM_CONSOLE, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 },
1821     { 1, IDM_LIST, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 },
1822     { 2, IDM_TRACER, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 },
1823     { 0, IDM_DOC, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 },
1824     { 4, IDM_WRD, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 },
1825     { 5, IDM_VSTMGR,
1826 #ifdef VST_LOADER_ENABLE
1827          TBSTATE_ENABLED,
1828 #else
1829          0, /* disabled */
1830 #endif
1831          TBSTYLE_BUTTON, 0, 0 },
1832     { 6, IDM_SOUNDSPEC,
1833 #ifdef SUPPORT_SOUNDSPEC
1834          TBSTATE_ENABLED,
1835 #else
1836          0, /* disabled */
1837 #endif
1838          TBSTYLE_CHECK, 0, 0 },
1839 };
1840
1841 static void InitSubWndToolbar(HWND hwnd)
1842 {
1843         TBADDBITMAP SubWndTbab;
1844   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_SUBWND,
1845                 TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
1846   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_SUBWND,
1847                 TB_SETBUTTONSIZE, (WPARAM)0, (LPARAM)MAKELONG(16,16));
1848   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_SUBWND,
1849         TB_ADDBUTTONS, (WPARAM)sizeof(SubWndTbb) / sizeof(TBBUTTON),(LPARAM)&SubWndTbb);
1850         SubWndTbab.hInst = hInst;
1851         SubWndTbab.nID =(int)IDB_BITMAP_SUBWND_BUTTON;
1852   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_SUBWND,
1853         TB_ADDBITMAP, (WPARAM)SUBWNDTOOLBAR_BITMAPITEMS, (LPARAM)&SubWndTbab);
1854   SendDlgItemMessage(hwnd, IDC_TOOLBARWINDOW_SUBWND,
1855                 TB_AUTOSIZE, 0, 0);
1856 }
1857
1858
1859 //-----------------------------------------------------------------------------
1860 // Canvas Window
1861
1862 #define MAPBAR_LIKE_TMIDI       // note bar view like tmidi
1863 #define TM_CANVAS_XMAX 160
1864 #define TM_CANVAS_YMAX 160
1865 #define TM_CANVASMAP_XMAX 16
1866 #define TM_CANVASMAP_YMAX 16
1867 #define CANVAS_XMAX 160
1868 #define CANVAS_YMAX 160
1869 #define CMAP_XMAX 16
1870 #define CMAP_YMAX 16
1871 #define CK_MAX_CHANNELS 16
1872 #define CMAP_MODE_16            1
1873 #define CMAP_MODE_32            2
1874 #define CMAP_MODE_64            3
1875 #define CMAP_MAX_CHANNELS       64
1876 struct Canvas_ {
1877         HWND hwnd;
1878         HWND hParentWnd;
1879         RECT rcMe;
1880         int Mode;
1881         HDC hdc;
1882         HDC hmdc;
1883         HGDIOBJ hgdiobj_hmdcprev;
1884         int UpdateAll;
1885         int PaintDone;
1886         HANDLE hPopupMenu;
1887         HANDLE hPopupMenuKeyboard;
1888 // Sleep mode
1889         RECT rcSleep;
1890         HBITMAP hbitmap;
1891         HBITMAP hBitmapSleep;
1892         int SleepUpdateFlag;
1893 // Map mode
1894         RECT rcMap;
1895         char MapMap[CMAP_MAX_CHANNELS][CMAP_YMAX];
1896         char MapMapOld[CMAP_MAX_CHANNELS][CMAP_YMAX];
1897         char MapBar[CMAP_MAX_CHANNELS];
1898         char MapBarOld[CMAP_MAX_CHANNELS];
1899         int MapDelay;
1900         int MapResidual;
1901         int MapUpdateFlag;
1902         int MapMode;
1903         int MapBarWidth;
1904         int MapBarMax;
1905    int MapCh;
1906    int MapPan[CMAP_MAX_CHANNELS];
1907    int MapPanOld[CMAP_MAX_CHANNELS];
1908    int MapSustain[CMAP_MAX_CHANNELS];
1909    int MapSustainOld[CMAP_MAX_CHANNELS];
1910    int MapExpression[CMAP_MAX_CHANNELS];
1911    int MapExpressionOld[CMAP_MAX_CHANNELS];
1912    int MapVolume[CMAP_MAX_CHANNELS];
1913    int MapVolumeOld[CMAP_MAX_CHANNELS];
1914    int MapPitchbend[CMAP_MAX_CHANNELS];
1915    int MapPitchbendOld[CMAP_MAX_CHANNELS];
1916    int MapChChanged;
1917         ChannelBitMask DrumChannel;
1918    RECT rcMapMap;
1919    RECT rcMapSub;
1920 // Keyboard mode
1921         RECT rcKeyboard;
1922         uint32 CKxnote[MAX_W32G_MIDI_CHANNELS][4];
1923         uint32 CKxnote_old[MAX_W32G_MIDI_CHANNELS][4];
1924         int CKNoteFrom;
1925    int CKNoteTo;
1926         int CKCh;
1927         int CKPart;
1928         RECT rcGSLCD;
1929         int8 GSLCD[16][16];
1930         int8 GSLCD_old[16][16];
1931         int KeyboardUpdateFlag;
1932         int xnote_reset;
1933 // misc
1934    Channel channel[MAX_W32G_MIDI_CHANNELS];
1935 } Canvas;
1936
1937 #define IDC_CANVAS 4242
1938
1939 static HWND hCanvasWnd;
1940 static char CanvasWndClassName[] = "TiMidity Canvas";
1941 static LRESULT CALLBACK CanvasWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
1942 static void CanvasPaintDo(void);
1943
1944 #define IDM_CANVAS_SLEEP                2321
1945 #define IDM_CANVAS_MAP        2322
1946 #define IDM_CANVAS_KEYBOARD   2323
1947 #define IDM_CANVAS_REDRAW     2324
1948 #define IDM_CANVAS_MAP16      2325
1949 #define IDM_CANVAS_MAP32      2326
1950 #define IDM_CANVAS_MAP64      2327
1951 #define IDM_CANVAS_KEYBOARD_A   2328
1952 #define IDM_CANVAS_KEYBOARD_B   2329
1953 #define IDM_CANVAS_KEYBOARD_C   2330
1954 #define IDM_CANVAS_KEYBOARD_D   2331
1955 #define IDM_CANVAS_GSLCD   2332
1956 static void InitCanvasWnd(HWND hwnd)
1957 {
1958         WNDCLASS wndclass ;
1959         hCanvasWnd = 0;
1960         wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_CLASSDC;
1961         wndclass.lpfnWndProc   = CanvasWndProc ;
1962         wndclass.cbClsExtra    = 0 ;
1963         wndclass.cbWndExtra    = 0 ;
1964         wndclass.hInstance     = hInst ;
1965         wndclass.hIcon         = NULL;
1966         wndclass.hCursor       = LoadCursor(0,IDC_ARROW) ;
1967         wndclass.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR + 1);
1968         wndclass.lpszMenuName  = NULL;
1969         wndclass.lpszClassName = CanvasWndClassName;
1970         RegisterClass(&wndclass);
1971    hCanvasWnd = CreateWindowEx(0,CanvasWndClassName,0,WS_CHILD,CW_USEDEFAULT,
1972         0,CANVAS_XMAX,CANVAS_YMAX,GetDlgItem(hwnd,IDC_RECT_CANVAS),0,hInst,0);
1973         CanvasInit(hCanvasWnd);
1974         CanvasReset();
1975         CanvasClear();
1976         CanvasReadPanelInfo(1);
1977         CanvasUpdate(1);
1978         CanvasPaintAll();
1979         ShowWindow(hCanvasWnd,SW_SHOW);
1980         UpdateWindow(hCanvasWnd);
1981 }
1982
1983 static LRESULT CALLBACK
1984 CanvasWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
1985 {
1986         switch (uMess)
1987         {
1988                 case WM_CREATE:
1989                         Canvas.hPopupMenuKeyboard = CreatePopupMenu();
1990                         AppendMenu(Canvas.hPopupMenuKeyboard,MF_STRING,IDM_CANVAS_KEYBOARD_A,"A Part");
1991                         AppendMenu(Canvas.hPopupMenuKeyboard,MF_STRING,IDM_CANVAS_KEYBOARD_B,"B Part");
1992                         AppendMenu(Canvas.hPopupMenuKeyboard,MF_STRING,IDM_CANVAS_KEYBOARD_C,"C Part");
1993                         AppendMenu(Canvas.hPopupMenuKeyboard,MF_STRING,IDM_CANVAS_KEYBOARD_D,"D Part");
1994                         Canvas.hPopupMenu = CreatePopupMenu();
1995                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_GSLCD,"LCD Mode");
1996                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_MAP16,"Map16 Mode");
1997                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_MAP32,"Map32 Mode");
1998                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_MAP64,"Map64 Mode");
1999                         //      AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_KEYBOARD,"Keyboard Mode");
2000                         AppendMenu(Canvas.hPopupMenu,MF_POPUP,(UINT)Canvas.hPopupMenuKeyboard,"Keyboard Mode");
2001                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_SLEEP,"Sleep Mode");
2002                         AppendMenu(Canvas.hPopupMenu,MF_SEPARATOR,0,0);
2003                         AppendMenu(Canvas.hPopupMenu,MF_STRING,IDM_CANVAS_REDRAW,"Redraw");
2004                         break;
2005                 case WM_DESTROY:
2006                         DestroyMenu ( Canvas.hPopupMenuKeyboard );
2007                         Canvas.hPopupMenuKeyboard = NULL;
2008                         break;
2009                 case WM_PAINT:
2010                         CanvasPaintDo();
2011                 return 0;
2012                 case WM_LBUTTONDBLCLK:
2013 #ifdef EXT_CONTROL_MAIN_THREAD
2014                         w32g_ext_control_main_thread(RC_EXT_MODE_CHANGE, 0);
2015 #else
2016                         w32g_send_rc(RC_EXT_MODE_CHANGE, 0);
2017 #endif
2018                         break;
2019       case WM_RBUTTONDOWN:
2020       {
2021         RECT rc;
2022         GetWindowRect(Canvas.hwnd,(RECT *)&rc);
2023                                 SetForegroundWindow ( Canvas.hwnd );
2024                         TrackPopupMenu(Canvas.hPopupMenu,TPM_TOPALIGN|TPM_LEFTALIGN,
2025                 rc.left+(int)LOWORD(lParam),rc.top+(int)HIWORD(lParam),
2026             0,Canvas.hwnd,NULL);
2027                                 PostMessage ( Canvas.hwnd, WM_NULL, 0, 0 );
2028       }
2029                         break;
2030                 case WM_COMMAND:
2031                         switch (LOWORD(wParam)) {
2032                         case IDM_CANVAS_GSLCD:
2033                                 CanvasChange(CANVAS_MODE_GSLCD);
2034                                 break;
2035                         case IDM_CANVAS_MAP16:
2036                                 Canvas.MapMode = CMAP_MODE_16;
2037                                 CanvasChange(CANVAS_MODE_MAP16);
2038                                 break;
2039                         case IDM_CANVAS_MAP32:
2040                                 Canvas.MapMode = CMAP_MODE_32;
2041                                 CanvasChange(CANVAS_MODE_MAP32);
2042                                 break;
2043                         case IDM_CANVAS_MAP64:
2044                                 Canvas.MapMode = CMAP_MODE_64;
2045                                 CanvasChange(CANVAS_MODE_MAP64);
2046                                 break;
2047                         case IDM_CANVAS_KEYBOARD:
2048                                 CanvasChange(CANVAS_MODE_KBD_A);
2049                                 break;
2050                         case IDM_CANVAS_KEYBOARD_A:
2051                                 Canvas.CKPart = 1;
2052                                 CanvasChange(CANVAS_MODE_KBD_A);
2053                                 break;
2054                         case IDM_CANVAS_KEYBOARD_B:
2055                                 Canvas.CKPart = 2;
2056                                 CanvasChange(CANVAS_MODE_KBD_B);
2057                                 break;
2058                         case IDM_CANVAS_KEYBOARD_C:
2059                                 Canvas.CKPart = 3;
2060                                 CanvasChange(CANVAS_MODE_KBD_C);
2061                                 break;
2062                         case IDM_CANVAS_KEYBOARD_D:
2063                                 Canvas.CKPart = 4;
2064                                 CanvasChange(CANVAS_MODE_KBD_D);
2065                                 break;
2066                         case IDM_CANVAS_SLEEP:
2067                                 CanvasChange(CANVAS_MODE_SLEEP);
2068                                 break;
2069                         case IDM_CANVAS_REDRAW:
2070 //                              PanelResetPart(PANELRESET_CHANNEL);
2071                                 CanvasReset();
2072                                 CanvasClear();
2073                                 CanvasReadPanelInfo(1);
2074                                 CanvasUpdate(1);
2075                                 CanvasPaintAll();
2076                                 break;
2077                         }
2078                         break;
2079                 default:
2080                         return DefWindowProc(hwnd,uMess,wParam,lParam) ;
2081         }
2082         return 0L;
2083 }
2084
2085 // Color
2086 #define CCR_FORE                RGB(0x00,0x00,0x00)
2087 #define CCR_BACK                RGB(0x00,0xf0,0x00)
2088 #define CCR_DFORE               RGB(0x70,0x00,0x00)
2089 #define CCR_DBACK               RGB(0x00,0xf0,0x00)
2090 #define CCR_LOW         RGB(0x80,0xd0,0x00)
2091 #define CCR_MIDDLE      RGB(0xb0,0xb0,0x00)
2092 #define CCR_HIGH                RGB(0xe0,0x00,0x00)
2093 // \90F\82ð m : n \82Å\8d¬\82º\82é
2094 static COLORREF HalfColorMN(COLORREF fc, COLORREF bc, int m, int n)
2095 {
2096         return fc*m/(m+n) + bc*n/(m+n);
2097 }
2098 static COLORREF HalfColor23(COLORREF fc, COLORREF bc)
2099 {
2100         return HalfColorMN(fc,bc,2,3);
2101 }
2102 static COLORREF HalfColor15(COLORREF fc, COLORREF bc)
2103 {
2104         return HalfColorMN(fc,bc,1,5);
2105 }
2106 #define CC_BACK                         0
2107 #define CC_FORE                         1
2108 #define CC_LOW                                  2
2109 #define CC_MIDDLE                               3
2110 #define CC_HIGH                         4
2111 #define CC_FORE_HALF                    11
2112 #define CC_LOW_HALF                     12
2113 #define CC_MIDDLE_HALF          13
2114 #define CC_HIGH_HALF                    14
2115 #define CC_FORE_WEAKHALF        15
2116 #define CC_DBACK                                21
2117 #define CC_DFORE                                22
2118 #define CC_DFORE_HALF           23
2119 #define CC_DFORE_WEAKHALF       24
2120 static COLORREF CanvasColor(int c)
2121 {
2122   switch(c){
2123         case CC_BACK:
2124                         return CCR_BACK;
2125         case CC_FORE:
2126                         return CCR_FORE;
2127         case CC_FORE_HALF:
2128                         return HalfColor15(CCR_FORE,CCR_BACK);
2129         case CC_FORE_WEAKHALF:
2130                         return HalfColor23(CCR_FORE,CCR_BACK);
2131         case CC_DBACK:
2132                         return CCR_DBACK;
2133         case CC_DFORE:
2134                         return CCR_DFORE;
2135         case CC_DFORE_HALF:
2136                         return HalfColor15(CCR_DFORE,CCR_DBACK);
2137         case CC_DFORE_WEAKHALF:
2138                         return HalfColor23(CCR_DFORE,CCR_DBACK);
2139         case CC_LOW:
2140                         return CCR_LOW;
2141         case CC_MIDDLE:
2142                         return CCR_MIDDLE;
2143         case CC_HIGH:
2144                         return CCR_HIGH;
2145         case CC_LOW_HALF:
2146                         return HalfColor23(CCR_LOW,CCR_BACK);
2147         case CC_MIDDLE_HALF:
2148                         return HalfColor23(CCR_MIDDLE,CCR_BACK);
2149         case CC_HIGH_HALF:
2150                         return HalfColor23(CCR_HIGH,CCR_BACK);
2151                 default:
2152                         return CCR_BACK;
2153         }
2154 }
2155
2156 static int CanvasOK = 0;
2157 static void CanvasInit(HWND hwnd)
2158 {
2159         RECT rc;
2160
2161         GDI_LOCK(); // gdi_lock
2162         Canvas.hwnd = hwnd;
2163         Canvas.hParentWnd = GetParent(Canvas.hwnd);
2164         GetClientRect(Canvas.hParentWnd,&rc);
2165         MoveWindow(Canvas.hwnd,0,0,rc.right-rc.left,rc.bottom-rc.top,FALSE);
2166         GetClientRect(Canvas.hwnd,(RECT *)&(Canvas.rcMe));
2167         Canvas.hdc = GetDC(Canvas.hwnd);
2168         Canvas.hbitmap = CreateCompatibleBitmap(Canvas.hdc,CANVAS_XMAX,CANVAS_YMAX);
2169         Canvas.hmdc = CreateCompatibleDC(Canvas.hdc);
2170         ReleaseDC(Canvas.hwnd,Canvas.hdc);
2171         Canvas.hBitmapSleep = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP_SLEEP));
2172         Canvas.hgdiobj_hmdcprev = SelectObject(Canvas.hmdc,Canvas.hbitmap);
2173
2174         SetRect((RECT *)&(Canvas.rcSleep),0,0,96,64);
2175         SetRect((RECT *)&(Canvas.rcMap),3,2+2,0,0);
2176         SetRect((RECT *)&(Canvas.rcKeyboard),1,1,0,0);
2177         SetRect((RECT *)&(Canvas.rcGSLCD),3,4,99,68);
2178    Canvas.rcMapMap.left = Canvas.rcMap.left;
2179    Canvas.rcMapMap.top = Canvas.rcMap.top;
2180    Canvas.rcMapMap.right = Canvas.rcMapMap.left + 6*16 - 1;
2181    Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*16 - 1;
2182    Canvas.rcMapSub.left = Canvas.rcMapMap.left;
2183    Canvas.rcMapSub.top = Canvas.rcMapMap.bottom + 2;
2184    Canvas.rcMapSub.right = Canvas.rcMapSub.left + 6*16 - 1;
2185    Canvas.rcMapSub.bottom = Canvas.rcMapSub.top +4+3+3+3+4 - 1;
2186         Canvas.MapDelay = 1;
2187         Canvas.MapResidual = 0;
2188         Canvas.MapMode = (MainWndInfo.CanvasMode == CANVAS_MODE_MAP32)
2189                         ? CMAP_MODE_32 : (MainWndInfo.CanvasMode == CANVAS_MODE_MAP64)
2190                         ? CMAP_MODE_64 : CMAP_MODE_16;
2191         Canvas.MapBarMax = 16;
2192         //      Canvas.CKNoteFrom = 24;
2193         //   Canvas.CKNoteTo = 24 + 96;
2194         Canvas.CKNoteFrom = 12;
2195    Canvas.CKNoteTo = Canvas.CKNoteFrom + 96 + 3;
2196         Canvas.CKCh = 16;
2197         Canvas.CKPart = (MainWndInfo.CanvasMode == CANVAS_MODE_KBD_B)
2198                 ? 2 : (MainWndInfo.CanvasMode == CANVAS_MODE_KBD_C)
2199                 ? 3 : (MainWndInfo.CanvasMode == CANVAS_MODE_KBD_D)
2200                 ? 4 : 1;
2201         Canvas.UpdateAll = 0;
2202         Canvas.Mode = (MainWndInfo.CanvasMode < CANVAS_MODE_GSLCD
2203                         || MainWndInfo.CanvasMode > CANVAS_MODE_SLEEP)
2204                         ? 1 : MainWndInfo.CanvasMode;
2205         Canvas.PaintDone = 0;
2206         GDI_UNLOCK(); // gdi_lock
2207         CanvasReset();
2208         CanvasOK = 1;
2209 }
2210
2211 // Canvas Map
2212
2213 static void CanvasMapClear(void)
2214 {
2215         HPEN hPen;
2216         HBRUSH hBrush;
2217         HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
2218         if(!CanvasOK)
2219         return;
2220         GDI_LOCK(); // gdi_lock
2221         hPen = CreatePen(PS_SOLID,1,CanvasColor(CC_BACK));
2222         hBrush = CreateSolidBrush(CanvasColor(CC_BACK));
2223         hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
2224         hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
2225         Rectangle(Canvas.hmdc,
2226         Canvas.rcMe.left,Canvas.rcMe.top,Canvas.rcMe.right,Canvas.rcMe.bottom);
2227         SelectObject(Canvas.hmdc, hgdiobj_hpen);
2228         DeleteObject(hPen);
2229         SelectObject(Canvas.hmdc, hgdiobj_hbrush);
2230         DeleteObject(hBrush);
2231         GDI_UNLOCK(); // gdi_lock
2232         InvalidateRect(hCanvasWnd, NULL, FALSE);
2233 }
2234
2235 static void CanvasMapReset(void)
2236 {
2237         int i,j,ch;
2238         if(!CanvasOK)
2239         return;
2240         switch(Canvas.MapMode){
2241    case CMAP_MODE_64:
2242                 Canvas.MapCh = 64;
2243 #ifdef MAPBAR_LIKE_TMIDI
2244                 Canvas.MapBarWidth = 5;
2245                 Canvas.MapBarMax = 4+1;
2246                 Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*Canvas.MapBarMax*4 + 6 - 1;
2247 #else
2248                 Canvas.MapBarWidth = 1;
2249                 Canvas.MapBarMax = 16;
2250                 Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*Canvas.MapBarMax - 1;
2251 #endif
2252                 break;
2253    case CMAP_MODE_32:
2254                 Canvas.MapCh = 32;
2255 #ifdef MAPBAR_LIKE_TMIDI
2256                 Canvas.MapBarWidth = 5;
2257                 Canvas.MapBarMax = 10+1;
2258                 Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*Canvas.MapBarMax*2 + 6 - 1;
2259 #else
2260                 Canvas.MapBarWidth = 2;
2261                 Canvas.MapBarMax = 16;
2262                 Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*Canvas.MapBarMax - 1;
2263 #endif
2264                 break;
2265    default:
2266    case CMAP_MODE_16:
2267                 Canvas.MapCh = 16;
2268                 Canvas.MapBarWidth = 5;
2269                 Canvas.MapBarMax = 16;
2270                 Canvas.rcMapMap.bottom = Canvas.rcMapMap.top + 3*Canvas.MapBarMax - 1;
2271                 break;
2272         }
2273         for(i=0;i<Canvas.MapCh;i++){
2274                 for(j=0;j<Canvas.MapBarMax;j++){
2275                 Canvas.MapMap[i][j] = CC_FORE_HALF;
2276                 Canvas.MapMapOld[i][j] = -1;
2277                 }
2278         Canvas.MapBar[i] = -1;
2279         Canvas.MapBarOld[i] = -1;
2280         }
2281         for(ch=0;ch<Canvas.MapCh;ch++){
2282                 Canvas.MapPan[ch] = Canvas.MapPanOld[ch] = 2;
2283                 Canvas.MapSustain[ch] = Canvas.MapSustainOld[ch] = 0;
2284                 Canvas.MapExpression[ch] = Canvas.MapExpressionOld[ch] = 0;
2285                 Canvas.MapVolume[ch] = Canvas.MapVolumeOld[ch] = 0;
2286                 Canvas.MapPitchbend[ch] = Canvas.MapPitchbendOld[ch] = 0x2000;
2287         }
2288         Canvas.MapResidual = -1;
2289         Canvas.MapUpdateFlag = 1;
2290         Canvas.PaintDone = 0;
2291 }
2292
2293 static void CanvasMapReadPanelInfo(int flag)
2294 {
2295         int ch,v;
2296
2297         if(!CanvasOK)
2298                 return;
2299         if(!PInfoOK)
2300         return;
2301    if(Canvas.UpdateAll)
2302         flag = 1;
2303         if(!Panel->changed && !flag)
2304         return;
2305         // Bar
2306         Canvas.DrumChannel = drumchannels;
2307         for(ch=0;ch<Canvas.MapCh;ch++){
2308                 Canvas.MapBarOld[ch] = Canvas.MapBar[ch];
2309                 if(Panel->v_flags[ch] == FLAG_NOTE_ON){
2310 #if 0
2311                         v = Panel->ctotal[ch]/8;
2312 #else
2313                         v = (int) Panel->ctotal[ch] * Canvas.MapBarMax / 128;
2314 #endif
2315                 } else {
2316         v = 0;
2317                 }
2318                 if(v<0) v = 0; else if(v>Canvas.MapBarMax-1) v = Canvas.MapBarMax-1;
2319                 if(v != Canvas.MapBar[ch]){
2320                         // \92x\89\84
2321                 if(Canvas.MapDelay){
2322                         int old = Canvas.MapBar[ch];
2323                                 if(Canvas.MapBar[ch]<0)
2324                                         Canvas.MapBar[ch] = v;
2325                                 else
2326                                         Canvas.MapBar[ch] = (old*10*1/3 + v*10*2/3)/10;
2327                                 if(old == Canvas.MapBar[ch]){
2328                                 if(v>old)
2329                                                 Canvas.MapBar[ch] = old + 1;
2330                                 else if(v<old)
2331                                                 Canvas.MapBar[ch] = old - 1;
2332                 }
2333                         } else
2334                                 Canvas.MapBar[ch] = v;
2335                 }
2336                 if(Canvas.MapBarOld[ch] != Canvas.MapBar[ch])
2337                         Canvas.MapResidual = -1;
2338         }
2339         // Sub
2340         if(Canvas.MapMode==CMAP_MODE_16){
2341                 Canvas.MapChChanged = 0;
2342                 for(ch=0;ch<Canvas.MapCh;ch++){
2343                         int changed = 0;
2344                         Canvas.MapPanOld[ch] = Canvas.MapPan[ch];
2345                         Canvas.MapSustainOld[ch] = Canvas.MapSustain[ch];
2346                         Canvas.MapExpressionOld[ch] = Canvas.MapExpression[ch];
2347                         Canvas.MapVolumeOld[ch] = Canvas.MapVolume[ch];
2348                         Canvas.MapPitchbendOld[ch] = Canvas.MapPitchbend[ch];
2349                         if(Panel->channel[ch].panning==NO_PANNING)
2350                 Canvas.MapPan[ch] = -1;
2351                         else {
2352                                 Canvas.MapPan[ch] = ( Panel->channel[ch].panning - 64 ) * 3 /128;
2353 //                              Canvas.MapPan[ch] = ( 64 - Panel->channel[ch].panning ) * 3 /128;
2354                                 Canvas.MapPan[ch] = SetValue(Canvas.MapPan[ch],-2,2) + 2;
2355                         }
2356                         if(Panel->channel[ch].sustain)
2357                                 Canvas.MapSustain[ch] = 5;
2358          else
2359                                 Canvas.MapSustain[ch] = 0;
2360                         //Canvas.MapSustain[ch] = SetValue(Canvas.MapSustain[ch],0,10);
2361 #if 0
2362                         Canvas.MapExpression[ch] = (Panel->channel[ch].expression * 11) >>8;
2363 #else
2364                     Canvas.MapExpression[ch] = (Panel->channel[ch].expression * 11) >>7;
2365 #endif
2366                         Canvas.MapExpression[ch] = SetValue(Canvas.MapExpression[ch],0,10);
2367 #if 0
2368                         Canvas.MapVolume[ch] = (Panel->channel[ch].volume * 11) >>8;
2369 #else
2370                         Canvas.MapVolume[ch] = (Panel->channel[ch].volume * 11) >>7;
2371 #endif
2372                         Canvas.MapVolume[ch] = SetValue(Canvas.MapVolume[ch],0,10);
2373                         Canvas.MapPitchbend[ch] = Panel->channel[ch].pitchbend;
2374                         if(Canvas.MapPanOld[ch]!=Canvas.MapPan[ch]) changed = 1;
2375                         if(Canvas.MapSustainOld[ch]!=Canvas.MapSustain[ch]) changed = 1;
2376                         if(Canvas.MapExpressionOld[ch]!=Canvas.MapExpression[ch]) changed = 1;
2377                         if(Canvas.MapVolumeOld[ch]!=Canvas.MapVolume[ch]) changed = 1;
2378                         if(Canvas.MapPitchbendOld[ch]!=Canvas.MapPitchbend[ch]) changed = 1;
2379                         if(changed)
2380                         Canvas.MapChChanged |= 1 << ch;
2381                 }
2382         }
2383 }
2384
2385 static void CanvasMapDrawMapBar(int flag)
2386 {
2387         int i,ch;
2388
2389         if(!CanvasOK)
2390                 return;
2391    if(Canvas.UpdateAll)
2392         flag = 1;
2393         if(!Canvas.MapResidual && !flag)
2394         return;
2395         Canvas.MapResidual = 0;
2396         for(ch=0;ch<Canvas.MapCh;ch++){
2397                 int drumflag = IS_SET_CHANNELMASK(Canvas.DrumChannel,ch);
2398                 char color1,color2,color3;
2399                 if(drumflag){
2400                         color1 = CC_DFORE;
2401                         color2 = CC_DFORE_WEAKHALF;
2402          color3 = CC_DFORE_HALF;
2403       } else {
2404                         color1 = CC_FORE;
2405                         color2 = CC_FORE_WEAKHALF;
2406          color3 = CC_FORE_HALF;
2407       }
2408                 for(i=0;i<Canvas.MapBarMax;i++){
2409                         int y = Canvas.MapBarMax-1-i;
2410                         Canvas.MapMapOld[ch][y] = Canvas.MapMap[ch][y];
2411                         if(i<=Canvas.MapBar[ch]){
2412                                 Canvas.MapMap[ch][y] = color1;
2413                                 Canvas.MapResidual = 1;
2414 #if 1           // \8ec\91\9c
2415                         } else if(i<=Canvas.MapBarOld[ch]){
2416                                 Canvas.MapMap[ch][y] = color2;
2417                                 Canvas.MapResidual = 1;
2418 #endif
2419                 } else {
2420                                 Canvas.MapMap[ch][y] = color3;
2421                         }
2422                 }
2423         }
2424         if(Canvas.MapResidual==0)
2425                 Canvas.MapResidual = -1;
2426 }
2427
2428 // #define CMAP_ALL_UPDATE
2429 static void CanvasMapUpdate(int flag)
2430 {
2431         RECT rc;
2432         int i,j;
2433         int change_flag = 0;
2434         if(!CanvasOK)
2435         return;
2436         CanvasMapDrawMapBar(flag);
2437    if(Canvas.UpdateAll)
2438         flag = 1;
2439         if(PInfoOK && Canvas.MapMode==CMAP_MODE_16){
2440    if(flag || Panel->changed){
2441                 int ch;
2442                 GDI_LOCK();
2443                 for(ch=0;ch<Canvas.MapCh;ch++){
2444                         int x,y;
2445          COLORREF color;
2446                         COLORREF colorFG, colorBG;
2447                         int drumflag = IS_SET_CHANNELMASK(Canvas.DrumChannel,ch);
2448                         if(!flag && !(Canvas.MapChChanged & (1<<ch)))
2449                 continue;
2450                         if(drumflag){
2451                                 colorFG = CanvasColor(CC_DFORE);
2452                                 colorBG = CanvasColor(CC_DFORE_HALF);
2453         } else {
2454                                 colorFG = CanvasColor(CC_FORE);
2455                                 colorBG = CanvasColor(CC_FORE_HALF);
2456         }
2457          rc.left = Canvas.rcMapSub.left + (5 + 1) * ch;
2458          rc.right = rc.left + 5 - 1;
2459                         // PAN
2460          rc.top = Canvas.rcMapSub.top;
2461          rc.bottom = rc.top + 3 - 1;
2462                                 for(x=rc.left;x<=rc.right;x++){
2463                                 for(y=rc.top;y<=rc.bottom;y++)
2464                                 SetPixelV(Canvas.hmdc,x,y,colorBG);
2465                                 }
2466                         if(Canvas.MapPan[ch]>=0){
2467                                 x = rc.left + Canvas.MapPan[ch];
2468                                 for(y=rc.top;y<=rc.bottom;y++)
2469                                 SetPixelV(Canvas.hmdc,x,y,colorFG);
2470                         }
2471          // SUSTAIN
2472          rc.top = rc.bottom + 2;
2473          rc.bottom = rc.top + 2 - 1;
2474                                 if(Canvas.MapSustain[ch]){
2475                                         for(x=rc.left;x<=rc.right;x++){
2476                                         for(y=rc.top;y<=rc.bottom;y++)
2477                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2478                                         }
2479                                 } else {
2480                                         for(x=rc.left;x<=rc.right;x++){
2481                                         for(y=rc.top;y<=rc.bottom;y++)
2482                                         SetPixelV(Canvas.hmdc,x,y,colorBG);
2483                                         }
2484          // EXPRESSION
2485          rc.top = rc.bottom + 2;
2486          rc.bottom = rc.top + 2 - 1;
2487                         for(i=1;i<=10;i++){
2488                         if(i <= Canvas.MapExpression[ch])
2489                 color = colorFG;
2490             else
2491                 color = colorBG;
2492                         x = rc.left + (i-1)/2;
2493                         y = rc.top + (i+1)%2;
2494                                 SetPixelV(Canvas.hmdc,x,y,color);
2495                         }
2496          // VOLUME
2497          rc.top = rc.bottom + 2;
2498          rc.bottom = rc.top + 2 - 1;
2499                         for(i=1;i<=10;i++){
2500                         if(i <= Canvas.MapVolume[ch])
2501                 color = colorFG;
2502             else
2503                 color = colorBG;
2504             x = rc.left + (i-1)/2;
2505                                 y = rc.top + (i+1)%2;
2506                                 SetPixelV(Canvas.hmdc,x,y,color);
2507                         }
2508          // PITCH_BEND
2509          rc.top = rc.bottom + 2;
2510          rc.bottom = rc.top + 3 - 1;
2511                                         for(x=rc.left;x<=rc.right;x++){
2512                                 for(y=rc.top;y<=rc.bottom;y++)
2513                                 SetPixelV(Canvas.hmdc,x,y,colorBG);
2514                                         }
2515          if(Canvas.MapPitchbend[ch]==-2){
2516                 y = rc.top + 1;
2517                                 for(x=rc.left;x<=rc.right;x++)
2518                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2519                                 y++;
2520                                 for(x=rc.left;x<=rc.right;x++)
2521                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2522                         } else if(Canvas.MapPitchbend[ch]>0x2000){
2523                 y = rc.top;
2524                                 for(x=rc.left;x<=rc.left;x++)
2525                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2526                                 y++;
2527                                 for(x=rc.left;x<=rc.left+2;x++)
2528                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2529                                 y++;
2530                                 for(x=rc.left;x<=rc.left+4;x++)
2531                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2532                         } else if(Canvas.MapPitchbend[ch]<0x2000){
2533                 y = rc.top;
2534                                 for(x=rc.right;x<=rc.right;x++)
2535                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2536                                 y++;
2537                                 for(x=rc.right-2;x<=rc.right;x++)
2538                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2539                                 y++;
2540                                 for(x=rc.right-4;x<=rc.right;x++)
2541                                         SetPixelV(Canvas.hmdc,x,y,colorFG);
2542          }
2543       }
2544       }
2545                         InvalidateRect(hCanvasWnd,(RECT *)&(Canvas.rcMapSub),FALSE);
2546                         GDI_UNLOCK();
2547    }
2548    }
2549         if(!Canvas.MapResidual && !flag)
2550         return;
2551         change_flag = 0;
2552 #ifndef MAPBAR_LIKE_TMIDI
2553         GDI_LOCK();
2554         for(i=0;i<Canvas.MapCh;i++){
2555                 for(j=0;j<Canvas.MapBarMax;j++){
2556                         if(Canvas.MapMap[i][j]!=Canvas.MapMapOld[i][j] || flag){
2557                                 int x,y;
2558                                 COLORREF color = CanvasColor(Canvas.MapMap[i][j]);
2559             rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * i;
2560             rc.right = rc.left -1 + Canvas.MapBarWidth;
2561             rc.top = Canvas.rcMap.top + (2 + 1) * j;
2562             rc.bottom = rc.top -1 + 2;
2563                                 for(x=rc.left;x<=rc.right;x++)
2564                                         for(y=rc.top;y<=rc.bottom;y++)
2565                                 SetPixelV(Canvas.hmdc,x,y,color);
2566                                 change_flag = 1;
2567                 }
2568         }
2569         }
2570         GDI_UNLOCK();
2571 #else
2572         GDI_LOCK();
2573         if(Canvas.MapMode==CMAP_MODE_16){
2574         for(i=0;i<Canvas.MapCh;i++){
2575                 for(j=0;j<Canvas.MapBarMax;j++){
2576                         if(Canvas.MapMap[i][j]!=Canvas.MapMapOld[i][j] || flag){
2577                                 int x,y;
2578                                 COLORREF color = CanvasColor(Canvas.MapMap[i][j]);
2579                                 rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * i;
2580                                 rc.right = rc.left -1 + Canvas.MapBarWidth;
2581                                 rc.top = Canvas.rcMap.top + (2 + 1) * j;
2582                                 rc.bottom = rc.top -1 + 2;
2583                                         for(x=rc.left;x<=rc.right;x++){
2584                                         for(y=rc.top;y<=rc.bottom;y++)
2585                                 SetPixelV(Canvas.hmdc,x,y,color);
2586                                         }
2587                                 change_flag = 1;
2588                 }
2589                 }
2590         }
2591         } else if(Canvas.MapMode==CMAP_MODE_32){
2592         for(i=0;i<Canvas.MapCh;i++){
2593                 for(j=0;j<Canvas.MapBarMax;j++){
2594                         if(Canvas.MapMap[i][j]!=Canvas.MapMapOld[i][j] || flag){
2595                                 int x,y;
2596                                 COLORREF color = CanvasColor(Canvas.MapMap[i][j]);
2597                                 if(i<=15){
2598                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * i;
2599                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2600                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j;
2601                                         rc.bottom = rc.top -1 + 2;
2602                                 } else {
2603                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * (i-16);
2604                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2605                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j + Canvas.MapBarMax*(2+1) + 2 ;
2606                                         rc.bottom = rc.top -1 + 2;
2607                                 }
2608                                 for(x=rc.left;x<=rc.right;x++)
2609                                         for(y=rc.top;y<=rc.bottom;y++)
2610                                         SetPixelV(Canvas.hmdc,x,y,color);
2611                                 change_flag = 1;
2612                 }
2613                 }
2614         }
2615         } else if(Canvas.MapMode==CMAP_MODE_64){
2616         for(i=0;i<Canvas.MapCh;i++){
2617                 for(j=0;j<Canvas.MapBarMax;j++){
2618                         if(Canvas.MapMap[i][j]!=Canvas.MapMapOld[i][j] || flag){
2619                                 int x,y;
2620                                 COLORREF color = CanvasColor(Canvas.MapMap[i][j]);
2621                                 if(i<=15){
2622                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * i;
2623                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2624                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j;
2625                                         rc.bottom = rc.top -1 + 2;
2626                                 } else if(i<=31){
2627                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * (i-16);
2628                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2629                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j + Canvas.MapBarMax*(2+1) + 2 ;
2630                                         rc.bottom = rc.top -1 + 2;
2631                                 } else if(i<=47){
2632                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * (i-32);
2633                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2634                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j + 2*Canvas.MapBarMax*(2+1) + 2*2 ;
2635                                         rc.bottom = rc.top -1 + 2;
2636                                 } else if(i<=63){
2637                                         rc.left = Canvas.rcMap.left + (Canvas.MapBarWidth + 1) * (i-48);
2638                                         rc.right = rc.left -1 + Canvas.MapBarWidth;
2639                                                 rc.top = -1 + Canvas.rcMap.top + (2 + 1) * j + 3*Canvas.MapBarMax*(2+1) + 3*2 ;
2640                                         rc.bottom = rc.top -1 + 2;
2641                                 }
2642                                 for(x=rc.left;x<=rc.right;x++)
2643                                         for(y=rc.top;y<=rc.bottom;y++)
2644                                         SetPixelV(Canvas.hmdc,x,y,color);
2645                                 change_flag = 1;
2646                 }
2647                 }
2648         }
2649         }
2650         GDI_UNLOCK();
2651 #endif
2652 #ifdef CMAP_ALL_UPDATE
2653         if(change_flag)
2654                 InvalidateRect(hCanvasWnd,NULL,FALSE);
2655 #else
2656         if(change_flag)
2657                 InvalidateRect(hCanvasWnd,(RECT *)&(Canvas.rcMapMap),FALSE);
2658 #endif
2659         if(Canvas.UpdateAll)
2660                 InvalidateRect(hCanvasWnd,NULL,FALSE);
2661         if(Canvas.MapResidual<0)
2662                 Canvas.MapResidual = 0;
2663 }
2664
2665 static void CanvasSleepClear(void)
2666 {
2667         RECT rc;
2668         HPEN hPen;
2669         HBRUSH hBrush;
2670         HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
2671         GDI_LOCK(); // gdi_lock
2672         hPen = CreatePen(PS_SOLID,1,GetSysColor(COLOR_SCROLLBAR));
2673         hBrush = CreateSolidBrush(GetSysColor(COLOR_SCROLLBAR));
2674         hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
2675         hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
2676         GetClientRect(Canvas.hwnd, &rc);
2677         Rectangle(Canvas.hmdc,rc.left,rc.top,rc.right,rc.bottom);
2678         SelectObject(Canvas.hmdc, hgdiobj_hpen);
2679         DeleteObject(hPen);
2680         SelectObject(Canvas.hmdc, hgdiobj_hbrush);
2681         DeleteObject(hBrush);
2682         GDI_UNLOCK(); // gdi_lock
2683         InvalidateRect(hCanvasWnd, NULL, FALSE);
2684 }
2685
2686 static void CanvasSleepReset(void)
2687 {
2688         Canvas.PaintDone = 0;
2689 }
2690
2691 static void CanvasSleepReadPanelInfo(int flag)
2692 {
2693 }
2694
2695 static int CanvasSleepDone = 0;
2696 static void CanvasSleepUpdate(int flag)
2697 {
2698         HDC hdc;
2699         RECT rc;
2700         int x,y;
2701         CanvasSleepReset();
2702         GDI_LOCK(); // gdi_lock
2703    hdc = CreateCompatibleDC(Canvas.hmdc);
2704         SelectObject(hdc,Canvas.hBitmapSleep);
2705         GetClientRect(Canvas.hwnd, &rc);
2706         x = (rc.right - rc.left - Canvas.rcSleep.right)/2;
2707         y = (rc.bottom - rc.top - Canvas.rcSleep.bottom)/2;
2708         if(x<0) x = 0;
2709         if(y<0) y = 0;
2710         BitBlt(Canvas.hmdc,x,y,Canvas.rcSleep.right,Canvas.rcSleep.bottom,hdc,0,0,SRCCOPY);
2711         DeleteDC(hdc);
2712         GDI_UNLOCK(); // gdi_lock
2713         if(flag) {InvalidateRect(hCanvasWnd, NULL, FALSE);}
2714 }
2715
2716 // Canvas GSLCD
2717
2718 static void CanvasGSLCDReset(void)
2719 {
2720         int i, j;
2721         for(i = 0; i < 16; i++) {
2722                 for(j = 0; j < 16; j++) {
2723                         Canvas.GSLCD[i][j] = 0;
2724                         Canvas.GSLCD_old[i][j] = 0;
2725                 }
2726         }
2727         Canvas.PaintDone = 0;
2728 }
2729
2730 static void CanvasGSLCDReadPanelInfo(int flag)
2731 {
2732         int i, j;
2733         if (!CanvasOK) {return;}
2734         if (!PInfoOK) {return;}
2735         if (Canvas.UpdateAll) {flag = 1;}
2736         if (!Panel->changed && !flag) {return;}
2737         for(i = 0; i < 16; i++) {
2738                 for(j = 0; j < 16; j++) {
2739                         Canvas.GSLCD_old[i][j] = Canvas.GSLCD[i][j];
2740                         Canvas.GSLCD[i][j] = Panel->GSLCD[i][j];
2741                 }
2742         }
2743 }
2744
2745 #define CGSLCD_BG RGB(0x00,0xf0,0x00)
2746 #define CGSLCD_ON RGB(0x00,0x00,0x00)
2747 #define CGSLCD_OFF RGB(0x00,0xc0,0x00)
2748 static void CanvasGSLCDUpdate(int flag)
2749 {
2750         int i, j, x, y, changed = 0;
2751         COLORREF colorON = CGSLCD_ON, colorOFF = CGSLCD_OFF;
2752         HPEN hPen;
2753         HBRUSH hBrush;
2754         HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
2755
2756         if(!PInfoOK) {return;}
2757         if(Canvas.UpdateAll) {flag = 1;}
2758         if(!Panel->changed && !flag) {return;}
2759         GDI_LOCK(); // gdi_lock
2760         for (i = 0; i < 16; i++) {
2761                 for (j = 0; j < 16; j++) {
2762                 x = Canvas.rcGSLCD.left + i * 6;
2763                         y = Canvas.rcGSLCD.top + j * 4;
2764                         if (flag || Canvas.GSLCD[i][j] != Canvas.GSLCD_old[i][j]) {
2765                                 changed = 1;
2766                                 if (Canvas.GSLCD[i][j] == 1) {
2767                                         hPen = CreatePen(PS_SOLID, 1, colorON);
2768                                         hBrush = CreateSolidBrush(colorON);
2769                                 }
2770                                 else {
2771                                         hPen = CreatePen(PS_SOLID, 1, colorOFF);
2772                                         hBrush = CreateSolidBrush(colorOFF);
2773                                 }
2774                                 hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
2775                                 hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
2776                                 Rectangle(Canvas.hmdc, x, y, x + 5, y + 3);
2777                                 SelectObject(Canvas.hmdc, hgdiobj_hpen);
2778                                 DeleteObject(hPen);
2779                                 SelectObject(Canvas.hmdc, hgdiobj_hbrush);
2780                                 DeleteObject(hBrush);
2781                         }
2782                 }
2783         }
2784         if (changed) {
2785                 GDI_UNLOCK();
2786         InvalidateRect(Canvas.hwnd, (RECT *)&Canvas.rcGSLCD, FALSE);
2787                 GDI_LOCK();
2788         }
2789         GDI_UNLOCK(); // gdi_lock
2790         if(flag) {InvalidateRect(hCanvasWnd, NULL, FALSE);}
2791 }
2792
2793 static void CanvasGSLCDClear(void)
2794 {
2795         HPEN hPen;
2796         HBRUSH hBrush;
2797         HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
2798         COLORREF BGcolor;
2799         if(!CanvasOK)
2800         return;
2801         GDI_LOCK(); // gdi_lock
2802         BGcolor = RGB(0,0,0);
2803         hPen = CreatePen(PS_SOLID,1,BGcolor);
2804         hBrush = CreateSolidBrush(BGcolor);
2805         hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
2806         hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
2807         Rectangle(Canvas.hmdc,
2808         Canvas.rcMe.left,Canvas.rcMe.top,Canvas.rcMe.right,Canvas.rcMe.bottom);
2809         SelectObject(Canvas.hmdc, hgdiobj_hpen);
2810         DeleteObject(hPen);
2811         SelectObject(Canvas.hmdc, hgdiobj_hbrush);
2812         DeleteObject(hBrush);
2813         BGcolor = CGSLCD_BG;
2814         hPen = CreatePen(PS_SOLID,1,BGcolor);
2815         hBrush = CreateSolidBrush(BGcolor);
2816         hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
2817         hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
2818         Rectangle(Canvas.hmdc,
2819         Canvas.rcMe.left + 1,Canvas.rcMe.top + 1,Canvas.rcMe.right - 1,Canvas.rcMe.bottom - 1);
2820         SelectObject(Canvas.hmdc, hgdiobj_hpen);
2821         DeleteObject(hPen);
2822         SelectObject(Canvas.hmdc, hgdiobj_hbrush);
2823         DeleteObject(hBrush);
2824         GDI_UNLOCK(); // gdi_lock
2825
2826         CanvasGSLCDReset();
2827         CanvasGSLCDReadPanelInfo(1);
2828         CanvasGSLCDUpdate(1);
2829         InvalidateRect(hCanvasWnd, NULL, FALSE);
2830 }
2831
2832 // Canvas Keyboard
2833
2834 static void CanvasKeyboardReset(void)
2835 {
2836         int i,j;
2837         int ChFrom = (Canvas.CKPart - 1) * Canvas.CKCh;
2838         int ChTo = Canvas.CKPart * Canvas.CKCh - 1;
2839         for(i=ChFrom;i<=ChTo;i++){
2840                 for(j=0;j<4;j++){
2841                         Canvas.CKxnote[i][j] = 0;
2842                         Canvas.CKxnote_old[i][j] = 0;
2843                 }
2844         }
2845         Canvas.PaintDone = 0;
2846 }
2847
2848 static void CanvasKeyboardReadPanelInfo(int flag)
2849 {
2850         int i,j;
2851         int ChFrom, ChTo;
2852         if(!CanvasOK)
2853                 return;
2854         if(!PInfoOK)
2855         return;
2856         ChFrom = (Canvas.CKPart - 1) * Canvas.CKCh;
2857         ChTo = Canvas.CKPart * Canvas.CKCh - 1;
2858    if(Canvas.UpdateAll)
2859         flag = 1;
2860         if(!Panel->changed && !flag)
2861         return;
2862         for(i=ChFrom;i<=ChTo;i++)
2863                 for(j=0;j<4;j++){
2864         Canvas.CKxnote_old[i][j] = Canvas.CKxnote[i][j];
2865                         Canvas.CKxnote[i][j] = Panel->xnote[i][j];
2866       }
2867 }
2868
2869 #define CK_KEY_BLACK    1
2870 #define CK_KEY_WHITE    2
2871 #define CK_ON RGB(0xff,0x00,0x00)
2872 #define CK_OFF_WHITE RGB(0xff,0xff,0xff)
2873 #define CK_OFF_BLACK RGB(0x00,0x00,0x00)
2874 #define CK_DOFF_WHITE RGB(0xcc,0xcc,0xcc)
2875 #define CK_DOFF_BLACK RGB(0x00,0x00,0x00)
2876 static void CanvasKeyboardUpdate(int flag)
2877 {
2878         int j,k,l;
2879    int channel;
2880         int ChFrom, ChTo;
2881
2882         if(!PInfoOK)
2883                 return;
2884    if(Canvas.UpdateAll)
2885         flag = 1;
2886         if(!COMPARE_CHANNELMASK(Canvas.DrumChannel,drumchannels))
2887         flag = 1;
2888         if(!Panel->changed && !flag)
2889         return;
2890         ChFrom = (Canvas.CKPart - 1) * Canvas.CKCh;
2891         ChTo = Canvas.CKPart * Canvas.CKCh - 1;
2892         GDI_LOCK(); // gdi_lock
2893         for(channel=ChFrom;channel<=ChTo;channel++){
2894                 int change_flag = 0;
2895                 int drumflag = IS_SET_CHANNELMASK(drumchannels,channel);
2896                 COLORREF colorON, colorOFF_WHITE, colorOFF_BLACK;
2897                 if(drumflag){
2898                         colorON = CK_ON;
2899          colorOFF_WHITE = CK_DOFF_WHITE;
2900          colorOFF_BLACK = CK_OFF_BLACK;
2901       } else {
2902                         colorON = CK_ON;
2903          colorOFF_WHITE = CK_OFF_WHITE;
2904          colorOFF_BLACK = CK_OFF_BLACK;
2905       }
2906                 for(j=0;j<4;j++){
2907                         int32 xnote, xnote_diff;
2908                         xnote = Canvas.CKxnote[channel][j];
2909                 xnote_diff = Canvas.CKxnote[channel][j] ^ Canvas.CKxnote_old[channel][j];
2910                         if(!flag && xnote_diff == 0)
2911                 continue;
2912                         for(k=0;k<32;k++){
2913                                 int key = 0;
2914                                 int KeyOn = 0;
2915                         int note = j*32+k;
2916             int reff = (int32)1 << k;
2917                                 int x,y;
2918                                 if(note < Canvas.CKNoteFrom || note > Canvas.CKNoteTo)
2919                         continue;
2920             if(!flag && !(xnote_diff & reff))
2921                 continue;
2922             if(xnote & reff)
2923                                         KeyOn = 1;
2924                                 note = note % 12;
2925             if(note == 1 || note == 3 || note == 6 || note == 8 || note == 10)
2926                                         key = CK_KEY_BLACK;
2927             else
2928                                         key = CK_KEY_WHITE;
2929                         x = Canvas.rcKeyboard.left + j * 32 + k - Canvas.CKNoteFrom;
2930                         y = Canvas.rcKeyboard.top + (channel - ChFrom) * 4;
2931                                 switch(key){
2932             case CK_KEY_BLACK:
2933                     if(KeyOn){
2934                                                 for(l=0;l<2;l++)
2935                                         SetPixelV(Canvas.hmdc,x,y+l,colorON);
2936                                                 SetPixelV(Canvas.hmdc,x,y+2,colorOFF_WHITE);
2937                     } else {
2938                                                 for(l=0;l<2;l++)
2939                                         SetPixelV(Canvas.hmdc,x,y+l,colorOFF_BLACK);
2940                                                 SetPixelV(Canvas.hmdc,x,y+2,colorOFF_WHITE);
2941                    }
2942                                         break;
2943             case CK_KEY_WHITE:
2944                     if(KeyOn){
2945                                                 SetPixelV(Canvas.hmdc,x,y,colorOFF_WHITE);
2946                                                 for(l=1;l<3;l++)
2947                                         SetPixelV(Canvas.hmdc,x,y+l,colorON);
2948                     } else {
2949                                                 SetPixelV(Canvas.hmdc,x,y,colorOFF_WHITE);
2950                                                 for(l=1;l<3;l++)
2951                                         SetPixelV(Canvas.hmdc,x,y+l,colorOFF_WHITE);
2952                    }
2953                                         break;
2954                                 default:
2955                 break;
2956                                 }
2957             change_flag = 1;
2958         }
2959                 }
2960                 if(change_flag){
2961          RECT rc;
2962                         GDI_UNLOCK();
2963                         GetClientRect(Canvas.hwnd,&rc);
2964          rc.top = Canvas.rcKeyboard.top + (channel - ChFrom) * 4;
2965                         rc.bottom = rc.top + 4;
2966         InvalidateRect(Canvas.hwnd, &rc, FALSE);
2967                         GDI_LOCK();
2968                 }
2969         }
2970         GDI_UNLOCK(); // gdi_lock
2971         if(flag)
2972                 InvalidateRect(hCanvasWnd, NULL, FALSE);
2973         Canvas.DrumChannel = drumchannels;
2974 }
2975
2976 static void CanvasKeyboardClear(void)
2977 {
2978         int i;
2979         HPEN hPen;
2980         HBRUSH hBrush;
2981         HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
2982         COLORREF FGcolor, BGcolor;
2983         HFONT hfont;
2984    HGDIOBJ hgdiobj;
2985         RECT rc;
2986         char buffer[16];
2987         if(!CanvasOK)
2988         return;
2989         GDI_LOCK(); // gdi_lock
2990 #if 0
2991         hPen = CreatePen(PS_SOLID,1,CanvasColor(CC_BACK));
2992         hBrush = CreateSolidBrush(CanvasColor(CC_BACK));
2993 #else
2994         FGcolor = RGB(0xff,0xff,0xff);
2995    BGcolor = RGB(0x00,0x00,0x00);
2996         hPen = CreatePen(PS_SOLID,1,BGcolor);
2997         hBrush = CreateSolidBrush(BGcolor);
2998 #endif
2999         hgdiobj_hpen = SelectObject(Canvas.hmdc, hPen);
3000         hgdiobj_hbrush = SelectObject(Canvas.hmdc, hBrush);
3001         Rectangle(Canvas.hmdc,
3002         Canvas.rcMe.left,Canvas.rcMe.top,Canvas.rcMe.right,Canvas.rcMe.bottom);
3003         SelectObject(Canvas.hmdc, hgdiobj_hpen);
3004         DeleteObject(hPen);
3005         SelectObject(Canvas.hmdc, hgdiobj_hbrush);
3006         DeleteObject(hBrush);
3007
3008         hfont = CreateFont(7,7,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3009                 DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3010         DEFAULT_PITCH | FF_DONTCARE,"Arial Bold");
3011         hgdiobj = SelectObject(Canvas.hmdc,hfont);
3012    SetTextAlign(Canvas.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3013         rc.left =       Canvas.rcMe.left+1 ;
3014         rc.top =                Canvas.rcMe.bottom-7;
3015         rc.right =      Canvas.rcMe.left+1 + 40;
3016         rc.bottom =     Canvas.rcMe.bottom;
3017         SetTextColor(Canvas.hmdc,RGB(0xff,0xff,0xff));
3018         SetBkColor(Canvas.hmdc,RGB(0x00,0x00,0x00));
3019         strcpy(buffer," ");
3020         ExtTextOut(Canvas.hmdc,rc.left,rc.top,ETO_CLIPPED|ETO_OPAQUE,&rc,
3021                 buffer,strlen(buffer),NULL);
3022         for(i=1;i<=(MAX_CHANNELS>>4);i++){
3023                 if(i==Canvas.CKPart){
3024                 SetTextColor(Canvas.hmdc,RGB(0xff,0xff,0xff));
3025                 SetBkColor(Canvas.hmdc,RGB(0x00,0x00,0x00));
3026       } else {
3027                 SetTextColor(Canvas.hmdc,RGB(0x80,0x80,0x80));
3028                 SetBkColor(Canvas.hmdc,RGB(0x00,0x00,0x00));
3029                 }
3030                 rc.left =       Canvas.rcMe.left+1 + 0 + (i-1)*24;
3031                 rc.top =                Canvas.rcMe.bottom-7;
3032                 rc.right =      Canvas.rcMe.left+1 + 0 + (i)*24 - 1;
3033                 rc.bottom =     Canvas.rcMe.bottom;
3034                 sprintf(buffer,"[%c]",i+'A'-1);
3035                 ExtTextOut(Canvas.hmdc,rc.left,rc.top,ETO_CLIPPED|ETO_OPAQUE,&rc,
3036                 buffer,strlen(buffer),NULL);
3037         }
3038    if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3039         SelectObject(Canvas.hmdc,hgdiobj);
3040         DeleteObject(hfont);
3041         GDI_UNLOCK(); // gdi_lock
3042
3043         CanvasKeyboardReset();
3044         CanvasKeyboardReadPanelInfo(1);
3045         CanvasKeyboardUpdate(1);
3046         InvalidateRect(hCanvasWnd, NULL, FALSE);
3047 }
3048
3049 // Canvas All
3050
3051 static void CanvasPaintDo(void)
3052 {
3053         RECT rc;
3054         if ( GetUpdateRect(Canvas.hwnd, &rc, FALSE) ) {
3055                 PAINTSTRUCT ps;
3056                 GDI_LOCK(); // gdi_lock
3057                 Canvas.hdc = BeginPaint(Canvas.hwnd, &ps);
3058                 BitBlt(Canvas.hdc,rc.left,rc.top,rc.right,rc.bottom,Canvas.hmdc,rc.left,rc.top,SRCCOPY);
3059                 EndPaint(Canvas.hwnd, &ps);
3060                 GDI_UNLOCK(); // gdi_lock
3061         }
3062 }
3063 void CanvasPaint(void)
3064 {
3065         Canvas.PaintDone = 0;
3066         UpdateWindow(hCanvasWnd);
3067 }
3068 void CanvasPaintAll(void)
3069 {
3070         InvalidateRect(hCanvasWnd, NULL, FALSE);
3071         CanvasPaint();
3072 }
3073
3074 void CanvasReset(void)
3075 {
3076         if (! CanvasOK)
3077                 return;
3078         switch (Canvas.Mode) {
3079         case CANVAS_MODE_GSLCD:
3080                 CanvasGSLCDReset();
3081                 break;
3082         case CANVAS_MODE_MAP16:
3083         case CANVAS_MODE_MAP32:
3084         case CANVAS_MODE_MAP64:
3085                 CanvasMapReset();
3086                 break;
3087         case CANVAS_MODE_KBD_A:
3088         case CANVAS_MODE_KBD_B:
3089         case CANVAS_MODE_KBD_C:
3090         case CANVAS_MODE_KBD_D:
3091                 CanvasKeyboardReset();
3092                 break;
3093         case CANVAS_MODE_SLEEP:
3094                 CanvasSleepReset();
3095                 break;
3096         }
3097 }
3098
3099 void CanvasClear(void)
3100 {
3101         if (! CanvasOK)
3102                 return;
3103         switch (Canvas.Mode) {
3104         case CANVAS_MODE_GSLCD:
3105                 CanvasGSLCDClear();
3106                 break;
3107         case CANVAS_MODE_MAP16:
3108         case CANVAS_MODE_MAP32:
3109         case CANVAS_MODE_MAP64:
3110                 CanvasMapClear();
3111                 break;
3112         case CANVAS_MODE_KBD_A:
3113         case CANVAS_MODE_KBD_B:
3114         case CANVAS_MODE_KBD_C:
3115         case CANVAS_MODE_KBD_D:
3116                 CanvasKeyboardClear();
3117                 break;
3118         case CANVAS_MODE_SLEEP:
3119                 CanvasSleepClear();
3120                 break;
3121         }
3122 }
3123
3124 void CanvasUpdate(int flag)
3125 {
3126         if (! CanvasOK)
3127                 return;
3128         switch (Canvas.Mode) {
3129         case CANVAS_MODE_GSLCD:
3130                 CanvasGSLCDUpdate(flag);
3131                 break;
3132         case CANVAS_MODE_MAP16:
3133         case CANVAS_MODE_MAP32:
3134         case CANVAS_MODE_MAP64:
3135                 CanvasMapUpdate(flag);
3136                 break;
3137         case CANVAS_MODE_KBD_A:
3138         case CANVAS_MODE_KBD_B:
3139         case CANVAS_MODE_KBD_C:
3140         case CANVAS_MODE_KBD_D:
3141                 CanvasKeyboardUpdate(flag);
3142                 break;
3143         case CANVAS_MODE_SLEEP:
3144                 CanvasSleepUpdate(flag);
3145                 break;
3146         }
3147 }
3148
3149 void CanvasReadPanelInfo(int flag)
3150 {
3151         if (! CanvasOK)
3152                 return;
3153         switch (Canvas.Mode) {
3154         case CANVAS_MODE_GSLCD:
3155                 CanvasGSLCDReadPanelInfo(flag);
3156                 break;
3157         case CANVAS_MODE_MAP16:
3158         case CANVAS_MODE_MAP32:
3159         case CANVAS_MODE_MAP64:
3160                 CanvasMapReadPanelInfo(flag);
3161                 break;
3162         case CANVAS_MODE_KBD_A:
3163         case CANVAS_MODE_KBD_B:
3164         case CANVAS_MODE_KBD_C:
3165         case CANVAS_MODE_KBD_D:
3166                 CanvasKeyboardReadPanelInfo(flag);
3167                 break;
3168         case CANVAS_MODE_SLEEP:
3169 //              CanvasSleepReadPanelInfo(flag);
3170                 break;
3171         }
3172 }
3173
3174 void CanvasChange(int mode)
3175 {
3176         if (mode != 0)
3177                 Canvas.Mode = mode;
3178         else {
3179                 if (Canvas.Mode == CANVAS_MODE_SLEEP)
3180                         Canvas.Mode = CANVAS_MODE_GSLCD;
3181                 else if (Canvas.Mode == CANVAS_MODE_GSLCD) {
3182                         Canvas.MapMode = CMAP_MODE_16;
3183                         Canvas.Mode = CANVAS_MODE_MAP16;
3184                 } else if (Canvas.Mode == CANVAS_MODE_MAP16) {
3185                         Canvas.MapMode = CMAP_MODE_32;
3186                         Canvas.Mode = CANVAS_MODE_MAP32;
3187                 } else if (Canvas.Mode == CANVAS_MODE_MAP32) {
3188                         Canvas.MapMode = CMAP_MODE_64;
3189                         Canvas.Mode = CANVAS_MODE_MAP64;
3190                 } else if (Canvas.Mode == CANVAS_MODE_MAP64) {
3191                         Canvas.CKPart = 1;
3192                         Canvas.Mode = CANVAS_MODE_KBD_A;
3193                 } else if (Canvas.Mode == CANVAS_MODE_KBD_A) {
3194                         Canvas.CKPart = 2;
3195                         Canvas.Mode = CANVAS_MODE_KBD_B;
3196                 } else if (Canvas.Mode == CANVAS_MODE_KBD_B) {
3197                         Canvas.CKPart = 3;
3198                         Canvas.Mode = CANVAS_MODE_KBD_C;
3199                 } else if (Canvas.Mode == CANVAS_MODE_KBD_C) {
3200                         Canvas.CKPart = 4;
3201                         Canvas.Mode = CANVAS_MODE_KBD_D;
3202                 } else if (Canvas.Mode == CANVAS_MODE_KBD_D)
3203                         Canvas.Mode = CANVAS_MODE_SLEEP;
3204         }
3205         MainWndInfo.CanvasMode = Canvas.Mode;
3206         CanvasReset();
3207         CanvasClear();
3208         CanvasReadPanelInfo(1);
3209         CanvasUpdate(1);
3210         CanvasPaintAll();
3211 }
3212
3213 int CanvasGetMode(void)
3214 {
3215         return Canvas.Mode;
3216 }
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245 //-----------------------------------------------------------------------------
3246 // Main Panel
3247 //  \83\81\83C\83\93\83p\83l\83\8b\83E\83C\83\93\83h\83E\8aÖ\98A
3248 //
3249 //
3250 //
3251 //
3252 //
3253 //
3254 //
3255
3256 #define MPANEL_XMAX 440
3257 #define MPANEL_YMAX 88
3258
3259 // update flag.
3260 #define MP_UPDATE_ALL               0xffffL
3261 #define MP_UPDATE_NONE              0x0000L
3262 #define MP_UPDATE_TITLE             0x0001L
3263 #define MP_UPDATE_FILE              0x0002L
3264 #define MP_UPDATE_TIME                  0x0004L
3265 #define MP_UPDATE_METRONOME             0x0008L
3266 #define MP_UPDATE_VOICES                0x0010L
3267 #define MP_UPDATE_MVOLUME               0x0020L
3268 #define MP_UPDATE_RATE                  0x0040L
3269 #define MP_UPDATE_PLAYLIST              0x0080L
3270 ///r
3271 #define MP_UPDATE_AQ_RATIO              0x0100L
3272
3273 #define MP_UPDATE_MISC              0x0200L
3274 #define MP_UPDATE_MESSAGE           0x0400L
3275 #define MP_UPDATE_BACKGROUND    0x0800L
3276 #define MP_UPDATE_KEYSIG                0x1000L
3277 #define MP_UPDATE_TEMPO                 0x2000L
3278
3279 #define MP_TITLE_MAX    256
3280 #define MP_FILE_MAX             256
3281 struct MPanel_ {
3282         HWND hwnd;
3283         HWND hParentWnd;
3284         HDC hdc;
3285    HDC hmdc;
3286         HGDIOBJ hgdiobj_hmdcprev;
3287         HBITMAP hbitmap;
3288         HBITMAP hbitmapBG;                      /* the background bitmap */
3289         HBITMAP hbitmapBGFilter;        /* the background bitmap filter */
3290         HFONT hfont;
3291         char Font[256];
3292         char FontLang[256];
3293         char FontLangFixed[256];
3294         RECT rcMe;
3295         RECT rcTitle;
3296         RECT rcFile;
3297         RECT rcTime;
3298         RECT rcVoices;
3299         RECT rcMVolume;
3300         RECT rcRate;
3301         RECT rcMetronome;
3302         RECT rcKeysig;
3303         RECT rcTempo;
3304         RECT rcList;
3305         RECT rcMisc;
3306         RECT rcMessage;
3307         char Title[MP_TITLE_MAX+1];
3308         char File[MP_FILE_MAX+1];
3309         int CurTime_h; int CurTime_m; int CurTime_s; int CurTime_ss;
3310         int TotalTime_h; int TotalTime_m; int TotalTime_s; int TotalTime_ss;
3311         int CurVoices;
3312         int MaxVoices;
3313    int MVolume;
3314         int Rate;
3315         int Meas;
3316         int Beat;
3317         char Keysig[7];
3318         int Key_offset;
3319         int Tempo;
3320         int Tempo_ratio;
3321         int PlaylistNum;
3322         int PlaylistMax;
3323         HFONT hFontTitle;
3324         HFONT hFontFile;
3325         HFONT hFontTime;
3326         HFONT hFontVoices;
3327         HFONT hFontMVolume;
3328         HFONT hFontRate;
3329         HFONT hFontMetronome;
3330         HFONT hFontKeysig;
3331         HFONT hFontTempo;
3332         HFONT hFontList;
3333         HFONT hFontMisc;
3334         HFONT hFontMessage;
3335         long UpdateFlag;
3336         COLORREF FGColor;
3337         COLORREF BGColor;
3338         COLORREF BGBGColor;
3339         enum play_system_modes play_system_mode;
3340         int current_file_info_file_type;
3341         int current_file_info_max_channel;
3342 ///r
3343         HFONT hFontAQ_RATIO;
3344         RECT rcAQ_RATIO;
3345         int aq_ratio;
3346         char rq_flag[2];
3347         char rv_flag[2];
3348         char rp_flag[2];
3349
3350 } MPanel;
3351 extern volatile int MPanelOK;
3352
3353 static struct MPanelMessageData_ {
3354         int len;        // \83\81\83b\83Z\81[\83W\83{\83b\83N\83X\82Ì\92·\82³\81B
3355         char buff[1024];        // \8eÀ\83o\83b\83t\83@\81B
3356         DWORD prevtime;
3357         int msec;       // \8eÀ\8ec\82è\95b\81B
3358         int pointer;            // \8c»\8dÝ\82Ì\83|\83C\83\93\83^\81B
3359
3360         char curbuff[1024];
3361         int curbuffsize;
3362         int curmode;    // \8c»\8dÝ\83\81\83b\83Z\81[\83W\82Ì\83\82\81[\83h\81B
3363         int curmsec;            // \8c»\8dÝ\83\81\83b\83Z\81[\83W\82Ì\8ec\82è\95b\81B
3364         char nextbuff[1024];
3365         int nextmode;   // \8c»\8dÝ\83\81\83b\83Z\81[\83W\82Ì\83\82\81[\83h\81B
3366         int nextmsec;           // \8c»\8dÝ\83\81\83b\83Z\81[\83W\82Ì\8ec\82è\95b\81B
3367 } MPanelMessageData;
3368 void MPanelMessageInit(void);
3369 void MPanelMessageAdd(char *message, int msec, int mode);
3370 void MPanelMessageClearAll(void);
3371 void MPanelMessageClear(void);
3372 void MPanelMessageNext(void);
3373 void MPanelMessageUpdate(void);
3374
3375 static HWND hPanelWnd;
3376 static char PanelWndClassName[] = "TiMidity Main Panel";
3377 static LRESULT CALLBACK PanelWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
3378 int MPanelMode = 0;
3379
3380 static void InitPanelWnd(HWND hwnd)
3381 {
3382         WNDCLASS wndclass ;
3383         hPanelWnd = 0;
3384         wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_CLASSDC;
3385         wndclass.lpfnWndProc   = PanelWndProc ;
3386         wndclass.cbClsExtra    = 0 ;
3387         wndclass.cbWndExtra    = 0 ;
3388         wndclass.hInstance     = hInst ;
3389         wndclass.hIcon         = NULL;
3390         wndclass.hCursor       = LoadCursor(0,IDC_ARROW) ;
3391         wndclass.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR + 1);
3392         wndclass.lpszMenuName  = NULL;
3393         wndclass.lpszClassName = PanelWndClassName;
3394         RegisterClass(&wndclass);
3395         hPanelWnd =
3396         CreateWindowEx(0,PanelWndClassName,0,WS_CHILD,
3397         CW_USEDEFAULT,0,MPANEL_XMAX,MPANEL_YMAX,
3398       GetDlgItem(hwnd,IDC_RECT_PANEL),0,hInst,0);
3399         MPanelInit(hPanelWnd);
3400         MPanelReset();
3401         MPanelReadPanelInfo(1);
3402         MPanelUpdateAll();
3403         MPanelPaintAll();
3404         UpdateWindow(hPanelWnd);
3405         ShowWindow(hPanelWnd,SW_SHOW);
3406 }
3407
3408 static void MPanelPaintDo(void);
3409 static LRESULT CALLBACK
3410 PanelWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
3411 {
3412         switch (uMess)
3413         {
3414                 case WM_CREATE:
3415                         break;
3416                 case WM_PAINT:
3417         MPanelPaintDo();
3418                 return 0;
3419                 case WM_LBUTTONDBLCLK:
3420 //                      MPanelReset();
3421                         MPanelReadPanelInfo(1);
3422                         MPanelUpdateAll();
3423                         MPanelPaintAll();
3424                         break;
3425                 case WM_DESTROY:
3426                         if(MPanel.hFontTitle!=NULL)
3427                                 DeleteObject(MPanel.hFontTitle);
3428                         if(MPanel.hFontFile!=NULL)
3429                                 DeleteObject(MPanel.hFontFile);
3430                         if(MPanel.hFontTime!=NULL)
3431                                 DeleteObject(MPanel.hFontTime);
3432                         if(MPanel.hFontVoices!=NULL)
3433                                 DeleteObject(MPanel.hFontVoices);
3434                         if(MPanel.hFontMVolume!=NULL)
3435                                 DeleteObject(MPanel.hFontMVolume);
3436                         if(MPanel.hFontRate!=NULL)
3437                                 DeleteObject(MPanel.hFontRate);
3438                         if (MPanel.hFontMetronome != NULL)
3439                                 DeleteObject(MPanel.hFontMetronome);
3440                         if (MPanel.hFontKeysig != NULL)
3441                                 DeleteObject(MPanel.hFontKeysig);
3442                         if (MPanel.hFontTempo != NULL)
3443                                 DeleteObject(MPanel.hFontTempo);
3444 ///r
3445                         if(MPanel.hFontAQ_RATIO!=NULL)
3446                                 DeleteObject(MPanel.hFontAQ_RATIO);
3447         //              if(MPanel.hFontList!=NULL)
3448         //                      DeleteObject(MPanel.hFontList);
3449
3450                         if(MPanel.hFontMisc!=NULL)
3451                                 DeleteObject(MPanel.hFontMisc);
3452                         if(MPanel.hFontMessage!=NULL)
3453                                 DeleteObject(MPanel.hFontMessage);
3454                         break;
3455                 default:
3456                         return DefWindowProc(hwnd,uMess,wParam,lParam) ;
3457         }
3458         return 0L;
3459 }
3460
3461 // Initialization of MPanel strucuter at once.
3462 volatile int MPanelOK = 0;
3463 static void MPanelInit(HWND hwnd)
3464 {
3465         RECT rc;
3466         int tmp;
3467         GDI_LOCK(); // gdi_lock
3468         MPanel.hwnd = hwnd;
3469         MPanel.hParentWnd = GetParent(MPanel.hwnd);
3470         GetClientRect(MPanel.hParentWnd,&rc);
3471         MoveWindow(MPanel.hwnd,0,0,rc.right-rc.left,rc.bottom-rc.top,FALSE);
3472         MPanel.hdc = GetDC(MPanel.hwnd);
3473         MPanel.hbitmap =
3474                 CreateCompatibleBitmap(MPanel.hdc,MPANEL_XMAX,MPANEL_YMAX);
3475         MPanel.hmdc =
3476         CreateCompatibleDC(MPanel.hdc);
3477         MPanel.hgdiobj_hmdcprev = SelectObject(MPanel.hmdc,MPanel.hbitmap);
3478         ReleaseDC(MPanel.hwnd,MPanel.hdc);
3479
3480         GetClientRect(MPanel.hwnd,&rc);
3481         // RECT reft,top,right,bottom
3482         SetRect(&(MPanel.rcMe),rc.left,rc.top,rc.right,rc.bottom);
3483         rc = MPanel.rcMe;
3484         SetRect(&(MPanel.rcTitle),      rc.left+2,      rc.top+2,                               rc.right-2,                             rc.top+2+14);
3485         SetRect(&(MPanel.rcFile),       rc.left+2,      rc.top+2+14+1,          rc.right-2,                             rc.top+2+14+1+12);
3486 #if 0
3487         SetRect(&(MPanel.rcTime),       rc.left+2,      rc.top+2+14+1+12+1,     rc.left+2+180,          rc.top+2+14+1+12+1+25);
3488         SetRect(&(MPanel.rcVoices), rc.right-2-36-1-24-48,      rc.top+2+14+1+12+1,     rc.right-2-36-1-24,     rc.top+2+14+1+12+1+12);
3489         SetRect(&(MPanel.rcMVolume),rc.right-2-36,                      rc.top+2+14+1+12+1,     rc.right-2,                             rc.top+2+14+1+12+1+12);
3490         SetRect(&(MPanel.rcRate),       rc.right-2-60-1-18-48,  rc.top+2+14+1+12+1+12+1,        rc.right-2-36-1,        rc.top+2+14+1+12+1+12+1+12);
3491         SetRect(&(MPanel.rcList),       rc.right-2-60,                          rc.top+2+14+1+12+1+12+1,        rc.right-2,                             rc.top+2+14+1+12+1+12+1+12);
3492         SetRect(&(MPanel.rcMisc),       rc.left+2,      rc.top+2+14+1+12+1+25+1,rc.right-2,rc.top+2+14+1+12+1+25+1+12);
3493         SetRect(&(MPanel.rcMessage),rc.left,rc.top,rc.right,rc.bottom);
3494 #else
3495         SetRect(&(MPanel.rcTime),
3496                         rc.left + 2,
3497                         rc.top + 2 + 14 + 1 + 12 + 1,
3498                         rc.left + 2 + 176,
3499                         rc.top + 2 + 14 + 1 + 12 + 1 + 25);
3500         SetRect(&(MPanel.rcVoices),
3501                         rc.left + 2 + 176 + 2,
3502                         rc.top + 2 + 14 + 1 + 12 + 1,
3503                         rc.left + 2 + 176 + 2 + 50,
3504                         rc.top + 2 + 14 + 1 + 12 + 1 + 12);
3505         SetRect(&(MPanel.rcRate),
3506                         rc.left + 2 + 176 + 2 + 50 + 2,
3507                         rc.top + 2 + 14 + 1 + 12 + 1,
3508                         rc.right - 2 - 38 - 2,
3509                         rc.top + 2 + 14 + 1 + 12 + 1 + 12);
3510         SetRect(&(MPanel.rcMVolume),
3511                         rc.right - 2 - 38,
3512                         rc.top + 2 + 14 + 1 + 12 + 1,
3513                         rc.right - 2,
3514                         rc.top + 2 + 14 + 1 + 12 + 1 + 12);
3515         SetRect(&(MPanel.rcMetronome),
3516                         rc.left + 2 + 176 - 40,
3517                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1,
3518                         rc.left + 2 + 176,
3519                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1 + 12);
3520         SetRect(&(MPanel.rcKeysig),
3521                         rc.left + 2 + 176 + 2,
3522                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1,
3523                         rc.right - 2 - 69 - 2,
3524                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12);
3525         SetRect(&(MPanel.rcTempo),
3526                         rc.right - 2 - 69,
3527                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1,
3528                         rc.right - 2,
3529                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12);
3530         SetRect(&(MPanel.rcMisc),
3531                         rc.left + 2 + 176 + 2,
3532                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1,
3533                         rc.right - 2 - 54 - 2,
3534                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1 + 12);
3535 ///r
3536 // test rcAQ_RATIO replace rcList
3537         SetRect(&(MPanel.rcAQ_RATIO),
3538                         rc.right - 2 - 54,
3539                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1,
3540                         rc.right - 2,
3541                         rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1 + 12);
3542         //SetRect(&(MPanel.rcList),
3543         //              rc.right - 2 - 54,
3544         //              rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1,
3545         //              rc.right - 2,
3546         //              rc.top + 2 + 14 + 1 + 12 + 1 + 12 + 1 + 12 + 1 + 12);
3547
3548         SetRect(&(MPanel.rcMessage),
3549                         rc.left + 2,
3550                         rc.top + 2 + 14 + 1 + 12 + 1 + 25 + 1,
3551                         rc.left + 2 + 176 - 40 - 2,
3552                         rc.top + 2 + 14 + 1 + 12 + 1 + 25 + 1 + 12);
3553 #endif
3554         MPanel.hFontTitle = NULL;
3555         MPanel.hFontFile = NULL;
3556         MPanel.hFontTime = NULL;
3557         MPanel.hFontVoices = NULL;
3558         MPanel.hFontMVolume = NULL;
3559         MPanel.hFontRate = NULL;
3560         MPanel.hFontMetronome = NULL;
3561         MPanel.hFontKeysig = NULL;
3562         MPanel.hFontTempo = NULL;
3563 ///r
3564         MPanel.hFontAQ_RATIO = NULL;
3565 //      MPanel.hFontList = NULL;
3566
3567
3568 //      strcpy(MPanel.Font,"Times New Roman");
3569         strcpy(MPanel.Font,"Arial Bold");
3570         switch(PlayerLanguage){
3571    case LANGUAGE_ENGLISH:
3572                 strcpy(MPanel.FontLang,"Times New Roman");
3573                 strcpy(MPanel.FontLangFixed,"Times New Roman");
3574         break;
3575         default:
3576         case LANGUAGE_JAPANESE:
3577                 strcpy(MPanel.FontLang,"\82l\82\82o\96¾\92©");
3578                 strcpy(MPanel.FontLangFixed,"\82l\82\96¾\92©");
3579 //              strcpy(MPanel.FontLang,"\82l\82\82o\83S\83V\83b\83N");
3580 //              strcpy(MPanel.FontLangFixed,"\82l\82\83S\83V\83b\83N");
3581                 break;
3582         }
3583         rc = MPanel.rcTitle;
3584         MPanel.hFontTitle =
3585                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3586                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3587         DEFAULT_PITCH | FF_DONTCARE,MPanel.FontLang);
3588         rc = MPanel.rcFile;
3589         MPanel.hFontFile =
3590                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3591                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3592         DEFAULT_PITCH | FF_DONTCARE,MPanel.FontLang);
3593         rc = MPanel.rcTime;
3594         MPanel.hFontTime =
3595                 CreateFont(24,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3596                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3597         DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3598         rc = MPanel.rcVoices;
3599         MPanel.hFontVoices =
3600                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3601                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3602         DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3603         rc = MPanel.rcMVolume;
3604         MPanel.hFontMVolume =
3605                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3606                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3607         DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3608         rc = MPanel.rcRate;
3609         MPanel.hFontRate =
3610                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3611                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3612         DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3613         rc = MPanel.rcMetronome;
3614         MPanel.hFontMetronome =
3615                         CreateFont(rc.bottom - rc.top + 1, 0, 0, 0, FW_DONTCARE,
3616                         FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
3617                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
3618                         DEFAULT_PITCH | FF_DONTCARE, MPanel.Font);
3619         rc = MPanel.rcKeysig;
3620         tmp = (rc.bottom - rc.top + 1) / 2;
3621         MPanel.hFontKeysig =
3622                         CreateFont(tmp * 2, tmp, 0, 0, FW_DONTCARE,
3623                         FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
3624                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
3625                         FIXED_PITCH | FF_DONTCARE, MPanel.Font);
3626         rc = MPanel.rcTempo;
3627         tmp = (rc.bottom - rc.top + 1) / 2;
3628         MPanel.hFontTempo =
3629                         CreateFont(tmp * 2, tmp, 0, 0, FW_DONTCARE,
3630                         FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
3631                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
3632                         FIXED_PITCH | FF_DONTCARE, MPanel.Font);
3633 ///r
3634         rc = MPanel.rcAQ_RATIO;
3635         MPanel.hFontAQ_RATIO =
3636                 CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3637                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3638         DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3639         //rc = MPanel.rcList;
3640         //MPanel.hFontList =
3641         //      CreateFont(rc.bottom-rc.top+1,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3642         //              DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3643  //             DEFAULT_PITCH | FF_DONTCARE,MPanel.Font);
3644
3645         rc = MPanel.rcMisc;
3646         tmp = (rc.bottom-rc.top+1)/2;
3647         MPanel.hFontMisc =
3648                 CreateFont(tmp*2,tmp,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3649                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3650         FIXED_PITCH | FF_DONTCARE,MPanel.Font);
3651         rc = MPanel.rcMessage;
3652         tmp = (rc.bottom-rc.top+1)/2;
3653         MPanel.hFontMessage = 
3654                 CreateFont(tmp*2,tmp,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
3655                         DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
3656         FIXED_PITCH | FF_DONTCARE,MPanel.FontLangFixed);
3657
3658         MPanelOK = 1;
3659         GDI_UNLOCK(); // gdi_lock
3660         MPanelMessageInit();
3661 }
3662
3663 // \83p\83l\83\8b\8d\\91¢\91Ì\82ð\83\8a\83Z\83b\83g\82·\82é\81B
3664 void MPanelReset(void)
3665 {
3666         if(!MPanelOK)
3667                 return;
3668         MPanel.Title[0] = '\0';
3669         MPanel.File[0] = '\0';
3670         strcpy(MPanel.Title,"No title.");
3671         strcpy(MPanel.File,"No file.");
3672         MPanel.CurTime_h = 0;
3673         MPanel.CurTime_m = 0;
3674         MPanel.CurTime_s = 0;
3675         MPanel.CurTime_ss = 0;
3676         MPanel.TotalTime_h = 0;
3677         MPanel.TotalTime_m = 0;
3678         MPanel.TotalTime_s = 0;
3679         MPanel.TotalTime_ss = 0;
3680         MPanel.CurVoices = 0;
3681         MPanel.MaxVoices = 0;
3682         MPanel.MVolume = 0;
3683         MPanel.Rate = 0;
3684         MPanel.Meas = 0;
3685         MPanel.Beat = 0;
3686         MPanel.Keysig[0] = '\0';
3687         MPanel.Key_offset = 0;
3688         MPanel.Tempo = 0;
3689         MPanel.Tempo_ratio = 0;
3690         MPanel.PlaylistNum = 0;
3691         MPanel.PlaylistMax = 0;
3692         MPanel.UpdateFlag = MP_UPDATE_ALL;
3693 //      MPanel.FGColor = RGB(0x00,0x00,0x00);
3694 //      MPanel.BGColor = RGB(0xff,0xff,0xff);
3695         MPanel.FGColor = RGB(0x00,0x00,0x00);
3696 //      MPanel.BGColor = RGB(0xc0,0xc0,0xc0);
3697         MPanel.BGColor = RGB(0xc0,0xc5,0xc3);
3698         MPanel.BGBGColor = RGB(0x60,0x60,0x60);
3699 #if 0
3700         if(MPanel.hFontTitle!=NULL)
3701         DeleteObject(MPanel.hFontTitle);
3702         if(MPanel.hFontFile!=NULL)
3703         DeleteObject(MPanel.hFontFile);
3704         if(MPanel.hFontTime!=NULL)
3705         DeleteObject(MPanel.hFontTime);
3706         if(MPanel.hFontVoices!=NULL)
3707         DeleteObject(MPanel.hFontVoices);
3708         if(MPanel.hFontMVolume!=NULL)
3709         DeleteObject(MPanel.hFontMVolume);
3710         if(MPanel.hFontRate!=NULL)
3711         DeleteObject(MPanel.hFontRate);
3712         if (MPanel.hFontMetronome != NULL)
3713                 DeleteObject(MPanel.hFontMetronome);
3714         if (MPanel.hFontKeysig != NULL)
3715                 DeleteObject(MPanel.hFontKeysig);
3716         if (MPanel.hFontTempo != NULL)
3717                 DeleteObject(MPanel.hFontTempo);
3718         if(MPanel.hFontList!=NULL)
3719         DeleteObject(MPanel.hFontList);
3720 #endif
3721         MPanel.play_system_mode = DEFAULT_SYSTEM_MODE;
3722         MPanel.current_file_info_file_type = IS_OTHER_FILE;
3723         MPanel.current_file_info_max_channel = -1;
3724         MPanelMessageClearAll();
3725 ///r
3726         MPanel.aq_ratio = 0;
3727         MPanel.rv_flag[0] = ' ';
3728         MPanel.rv_flag[1] = '\0';
3729         MPanel.rq_flag[0] = ' ';
3730         MPanel.rq_flag[1] = '\0';
3731         MPanel.rp_flag[0] = ' ';
3732         MPanel.rp_flag[1] = '\0';
3733 }
3734
3735 // \83p\83l\83\8b\8d\\91¢\91Ì\82ð\8c³\82É\8dX\90V\82·\82é\81B
3736 void MPanelUpdate(void)
3737 {
3738         if(!MPanelOK)
3739                 return;
3740         MPanelMessageUpdate();
3741         if(MPanel.UpdateFlag==MP_UPDATE_NONE)
3742                 return;
3743         if(MPanel.UpdateFlag & MP_UPDATE_BACKGROUND){
3744                 // \83r\83b\83g\83}\83b\83v\82ð\93\\82è\95t\82¯\82é\82ª\8d¡\82Í\93h\82è\82Â\82Ô\82µ\81B
3745                 HPEN hPen;
3746       HBRUSH hBrush;
3747 //              COLORREF color = MPanel.FGColor;
3748                 COLORREF color = MPanel.BGBGColor;
3749                 RECT rc = MPanel.rcMe;
3750                 HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
3751                 GDI_LOCK(); // gdi_lock
3752                 hPen = CreatePen(PS_SOLID,1,color);
3753                 hBrush = CreateSolidBrush(color);
3754                 hgdiobj_hpen = SelectObject(MPanel.hmdc, hPen);
3755                 hgdiobj_hbrush = SelectObject(MPanel.hmdc, hBrush);
3756                 Rectangle(MPanel.hmdc,rc.left,rc.top,rc.right,rc.bottom);
3757                 SelectObject(MPanel.hmdc, hgdiobj_hpen);
3758                 DeleteObject(hPen);
3759                 SelectObject(MPanel.hmdc, hgdiobj_hbrush);
3760                 DeleteObject(hBrush);
3761                 GDI_UNLOCK(); // gdi_lock
3762                 InvalidateRect(MPanel.hwnd,&rc, FALSE);
3763    }
3764         if(MPanel.UpdateFlag & MP_UPDATE_TITLE){
3765                 HGDIOBJ hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontTitle);
3766                 GDI_LOCK(); // gdi_lock
3767                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3768                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3769         //#include "w32g2_c.h"
3770         SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3771                 ExtTextOut(MPanel.hmdc,MPanel.rcTitle.left,MPanel.rcTitle.top,
3772                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcTitle),
3773                 MPanel.Title,strlen(MPanel.Title),NULL);
3774                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3775                         SelectObject(MPanel.hmdc,hgdiobj);
3776                 GDI_UNLOCK(); // gdi_lock
3777                 InvalidateRect(hPanelWnd, &(MPanel.rcTitle), FALSE);
3778         }
3779         if(MPanel.UpdateFlag & MP_UPDATE_FILE){
3780                 HGDIOBJ hgdiobj;
3781                 GDI_LOCK(); // gdi_lock
3782                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontFile);
3783                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3784                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3785                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3786                 ExtTextOut(MPanel.hmdc,MPanel.rcFile.left,MPanel.rcFile.top,
3787                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcFile),
3788                 MPanel.File,strlen(MPanel.File),NULL);
3789                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3790                         SelectObject(MPanel.hmdc,hgdiobj);
3791                 GDI_UNLOCK(); // gdi_lock
3792                 InvalidateRect(hPanelWnd, &(MPanel.rcFile), FALSE);
3793    }
3794         if(MPanel.UpdateFlag & MP_UPDATE_TIME){
3795                 char buffer[256];
3796                 HGDIOBJ hgdiobj;
3797                 GDI_LOCK(); // gdi_lock
3798                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontTime);
3799         sprintf(buffer," %02d:%02d:%02d/%02d:%02d:%02d",
3800                         MPanel.CurTime_h,MPanel.CurTime_m,MPanel.CurTime_s,
3801                 MPanel.TotalTime_h,MPanel.TotalTime_m,MPanel.TotalTime_s);
3802                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3803                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3804                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3805                 ExtTextOut(MPanel.hmdc,MPanel.rcTime.left,MPanel.rcTime.top,
3806                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcTime),
3807                 buffer,strlen(buffer),NULL);
3808                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3809                         SelectObject(MPanel.hmdc,hgdiobj);
3810                 GDI_UNLOCK(); // gdi_lock
3811                 InvalidateRect(hPanelWnd, &(MPanel.rcTime), FALSE);
3812    }
3813         if(MPanel.UpdateFlag & MP_UPDATE_VOICES){
3814                 char buffer[256];
3815                 HGDIOBJ hgdiobj;
3816                 GDI_LOCK(); // gdi_lock
3817                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontVoices);
3818         sprintf(buffer," %03d/%03d",MPanel.CurVoices,MPanel.MaxVoices);
3819                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3820                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3821                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3822                 ExtTextOut(MPanel.hmdc,MPanel.rcVoices.left,MPanel.rcVoices.top,
3823                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcVoices),
3824                 buffer,strlen(buffer),NULL);
3825                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3826                         SelectObject(MPanel.hmdc,hgdiobj);
3827                 GDI_UNLOCK(); // gdi_lock
3828                 InvalidateRect(hPanelWnd, &(MPanel.rcVoices), FALSE);
3829    }
3830         if(MPanel.UpdateFlag & MP_UPDATE_MVOLUME){
3831                 char buffer[256];
3832                 HGDIOBJ hgdiobj;
3833                 GDI_LOCK(); // gdi_lock
3834                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontVoices);
3835         sprintf(buffer," %03d%%",MPanel.MVolume);
3836                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3837                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3838                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3839                 ExtTextOut(MPanel.hmdc,MPanel.rcMVolume.left,MPanel.rcMVolume.top,
3840                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMVolume),
3841                 buffer,strlen(buffer),NULL);
3842                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3843                         SelectObject(MPanel.hmdc,hgdiobj);
3844                 GDI_UNLOCK(); // gdi_lock
3845                 InvalidateRect(hPanelWnd, &(MPanel.rcMVolume), FALSE);
3846    }
3847         if(MPanel.UpdateFlag & MP_UPDATE_RATE){
3848                 char buffer[256];
3849                 HGDIOBJ hgdiobj;
3850                 GDI_LOCK(); // gdi_lock
3851                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontRate);
3852         sprintf(buffer," %05dHz",MPanel.Rate);
3853                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3854                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3855                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3856                 ExtTextOut(MPanel.hmdc,MPanel.rcRate.left,MPanel.rcRate.top,
3857                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcRate),
3858                 buffer,strlen(buffer),NULL);
3859                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3860                         SelectObject(MPanel.hmdc,hgdiobj);
3861                 GDI_UNLOCK(); // gdi_lock
3862                 InvalidateRect(hPanelWnd, &(MPanel.rcRate), FALSE);
3863    }
3864         if (MPanel.UpdateFlag & MP_UPDATE_METRONOME) {
3865                 char buffer[256];
3866                 HGDIOBJ hgdiobj;
3867                 
3868                 GDI_LOCK(); // gdi_lock
3869                 hgdiobj = SelectObject(MPanel.hmdc, MPanel.hFontMetronome);
3870                 sprintf(buffer, " %03d.%02d", MPanel.Meas, MPanel.Beat);
3871                 SetTextColor(MPanel.hmdc, MPanel.FGColor);
3872                 SetBkColor(MPanel.hmdc, MPanel.BGColor);
3873                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3874                 ExtTextOut(MPanel.hmdc,
3875                                 MPanel.rcMetronome.left, MPanel.rcMetronome.top,
3876                                 ETO_CLIPPED | ETO_OPAQUE, &(MPanel.rcMetronome),
3877                                 buffer, strlen(buffer), NULL);
3878                 if ((HGDIOBJ) hgdiobj != (HGDIOBJ) NULL
3879                                 && (HGDIOBJ) hgdiobj != (HGDIOBJ) GDI_ERROR)
3880                         SelectObject(MPanel.hmdc, hgdiobj);
3881                 GDI_UNLOCK(); // gdi_lock
3882                 InvalidateRect(hPanelWnd, &(MPanel.rcMetronome), FALSE);
3883         }
3884         if (MPanel.UpdateFlag & MP_UPDATE_KEYSIG) {
3885                 char buffer[256];
3886                 HGDIOBJ hgdiobj;
3887                 
3888                 GDI_LOCK(); // gdi_lock
3889                 hgdiobj = SelectObject(MPanel.hmdc, MPanel.hFontKeysig);
3890                 if (MPanel.Keysig[0] == '\0')
3891                         strcpy(MPanel.Keysig, "-- ---");
3892                 sprintf(buffer, "%s (%+03d)", MPanel.Keysig, MPanel.Key_offset);
3893                 SetTextColor(MPanel.hmdc, MPanel.FGColor);
3894                 SetBkColor(MPanel.hmdc, MPanel.BGColor);
3895                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3896                 ExtTextOut(MPanel.hmdc,
3897                                 MPanel.rcKeysig.left + 2, MPanel.rcKeysig.top,
3898                                 ETO_CLIPPED | ETO_OPAQUE, &(MPanel.rcKeysig),
3899                                 buffer, strlen(buffer), NULL);
3900                 if ((HGDIOBJ) hgdiobj != (HGDIOBJ) NULL
3901                                 && (HGDIOBJ) hgdiobj != (HGDIOBJ) GDI_ERROR)
3902                         SelectObject(MPanel.hmdc, hgdiobj);
3903                 GDI_UNLOCK(); // gdi_lock
3904                 InvalidateRect(hPanelWnd, &(MPanel.rcKeysig), FALSE);
3905         }
3906         if (MPanel.UpdateFlag & MP_UPDATE_TEMPO) {
3907                 char buffer[256];
3908                 HGDIOBJ hgdiobj;
3909                 
3910                 GDI_LOCK(); // gdi_lock
3911                 hgdiobj = SelectObject(MPanel.hmdc, MPanel.hFontTempo);
3912                 sprintf(buffer, "%3d (%03d %%)", MPanel.Tempo, MPanel.Tempo_ratio);
3913                 SetTextColor(MPanel.hmdc, MPanel.FGColor);
3914                 SetBkColor(MPanel.hmdc, MPanel.BGColor);
3915                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3916                 ExtTextOut(MPanel.hmdc,
3917                                 MPanel.rcTempo.left + 2, MPanel.rcTempo.top,
3918                                 ETO_CLIPPED | ETO_OPAQUE, &(MPanel.rcTempo),
3919                                 buffer, strlen(buffer), NULL);
3920                 if ((HGDIOBJ) hgdiobj != (HGDIOBJ) NULL
3921                                 && (HGDIOBJ) hgdiobj != (HGDIOBJ) GDI_ERROR)
3922                         SelectObject(MPanel.hmdc, hgdiobj);
3923                 GDI_UNLOCK(); // gdi_lock
3924                 InvalidateRect(hPanelWnd, &(MPanel.rcTempo), FALSE);
3925         }
3926 ///r
3927         if(MPanel.UpdateFlag & MP_UPDATE_AQ_RATIO){
3928                 char buffer[256];
3929                 HGDIOBJ hgdiobj;
3930                 GDI_LOCK(); // gdi_lock
3931                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontAQ_RATIO);
3932                 sprintf(buffer,"%04d%%%s%s%s",MPanel.aq_ratio,MPanel.rq_flag,MPanel.rv_flag,MPanel.rp_flag);
3933                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
3934                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
3935                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3936                 ExtTextOut(MPanel.hmdc,MPanel.rcAQ_RATIO.left,MPanel.rcAQ_RATIO.top,
3937                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcAQ_RATIO),
3938                 buffer,strlen(buffer),NULL);
3939                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3940                         SelectObject(MPanel.hmdc,hgdiobj);
3941                 GDI_UNLOCK(); // gdi_lock
3942                 InvalidateRect(hPanelWnd, &(MPanel.rcAQ_RATIO), FALSE);
3943    }
3944         //if(MPanel.UpdateFlag & MP_UPDATE_PLAYLIST){
3945         //      char buffer[256];
3946         //      HGDIOBJ hgdiobj;
3947         //      GDI_LOCK(); // gdi_lock
3948         //      hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontList);
3949  //     sprintf(buffer," %04d/%04d",MPanel.PlaylistNum,MPanel.PlaylistMax);
3950         //      SetTextColor(MPanel.hmdc,MPanel.FGColor);
3951         //      SetBkColor(MPanel.hmdc,MPanel.BGColor);
3952         //      SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
3953         //      ExtTextOut(MPanel.hmdc,MPanel.rcList.left,MPanel.rcList.top,
3954  //             ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcList),
3955  //             buffer,strlen(buffer),NULL);
3956         //      if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
3957         //              SelectObject(MPanel.hmdc,hgdiobj);
3958         //      GDI_UNLOCK(); // gdi_lock
3959         //      InvalidateRect(hPanelWnd, &(MPanel.rcList), FALSE);
3960  //  }
3961         if(MPanel.UpdateFlag & MP_UPDATE_MISC){
3962                 char buffer[256];
3963                 HGDIOBJ hgdiobj;
3964                 GDI_LOCK(); // gdi_lock
3965                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontMisc);
3966                 buffer[0] = '\0';
3967                 switch(MPanel.play_system_mode){
3968         case GM_SYSTEM_MODE:
3969                         strcat(buffer,"[GM]");
3970                         break;
3971         case GM2_SYSTEM_MODE:
3972                         strcat(buffer,"[G2]");
3973                         break;
3974         case GS_SYSTEM_MODE:
3975                         strcat(buffer,"[GS]");
3976                         break;
3977         case XG_SYSTEM_MODE:
3978                         strcat(buffer,"[XG]");
3979                         break;
3980         case SD_SYSTEM_MODE:
3981                         strcat(buffer,"[SD]");
3982                         break;
3983         case KG_SYSTEM_MODE:
3984                         strcat(buffer,"[KG]");
3985                         break;
3986         case CM_SYSTEM_MODE:
3987                         strcat(buffer,"[CM]");
3988                         break;
3989                 default:
3990                 case DEFAULT_SYSTEM_MODE:
3991                         strcat(buffer,"[--]");
3992                         break;
3993                 }
3994                 switch(MPanel.current_file_info_file_type){
3995                 case  IS_SMF_FILE:
3996                         strcat(buffer,"[SMF]");
3997                         break;
3998                 case  IS_MCP_FILE:
3999                         strcat(buffer,"[MCP]");
4000                         break;
4001                 case  IS_RCP_FILE:
4002                         strcat(buffer,"[RCP]");
4003                         break;
4004                 case  IS_R36_FILE:
4005                         strcat(buffer,"[R36]");
4006                         break;
4007                 case  IS_G18_FILE:
4008                         strcat(buffer,"[G18]");
4009                         break;
4010                 case  IS_G36_FILE:
4011                         strcat(buffer,"[G36]");
4012                         break;
4013                 case  IS_SNG_FILE:
4014                         strcat(buffer,"[SNG]");
4015                         break;
4016                 case  IS_MM2_FILE:
4017                         strcat(buffer,"[MM2]");
4018                         break;
4019                 case  IS_MML_FILE:
4020                         strcat(buffer,"[MML]");
4021                         break;
4022                 case  IS_FM_FILE:
4023                         strcat(buffer,"[FM ]");
4024                         break;
4025                 case  IS_FPD_FILE:
4026                         strcat(buffer,"[FPD]");
4027                         break;
4028                 case  IS_MOD_FILE:
4029                         strcat(buffer,"[MOD]");
4030                         break;
4031                 case  IS_669_FILE:
4032                         strcat(buffer,"[669]");
4033                         break;
4034                 case  IS_MTM_FILE:
4035                         strcat(buffer,"[MTM]");
4036                         break;
4037                 case  IS_STM_FILE:
4038                         strcat(buffer,"[STM]");
4039                         break;
4040                 case  IS_S3M_FILE:
4041                         strcat(buffer,"[S3M]");
4042                         break;
4043                 case  IS_ULT_FILE:
4044                         strcat(buffer,"[ULT]");
4045                         break;
4046                 case  IS_XM_FILE:
4047                         strcat(buffer,"[XM ]");
4048                         break;
4049                 case  IS_FAR_FILE:
4050                         strcat(buffer,"[FAR]");
4051                         break;
4052                 case  IS_WOW_FILE:
4053                         strcat(buffer,"[WOW]");
4054                         break;
4055                 case  IS_OKT_FILE:
4056                         strcat(buffer,"[OKT]");
4057                         break;
4058                 case  IS_DMF_FILE:
4059                         strcat(buffer,"[DMF]");
4060                         break;
4061                 case  IS_MED_FILE:
4062                         strcat(buffer,"[MED]");
4063                         break;
4064                 case  IS_IT_FILE:
4065                         strcat(buffer,"[IT ]");
4066                         break;
4067                 case  IS_PTM_FILE:
4068                         strcat(buffer,"[PTM]");
4069                         break;
4070                 case  IS_MFI_FILE:
4071                         strcat(buffer,"[MFI]");
4072                         break;
4073                 default:
4074                 case  IS_OTHER_FILE:
4075                         strcat(buffer,"[---]");
4076                         break;
4077                 }
4078                 if(MPanel.current_file_info_max_channel>=0){
4079         char local[16];
4080          sprintf(local,"[%02dch]",MPanel.current_file_info_max_channel+1);
4081                         strcat(buffer,local);
4082       }else
4083                         strcat(buffer,"[--ch]");
4084                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
4085                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
4086                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
4087                 ExtTextOut(MPanel.hmdc,MPanel.rcMisc.left,MPanel.rcMisc.top,
4088                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMisc),
4089                 buffer,strlen(buffer),NULL);
4090                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
4091                         SelectObject(MPanel.hmdc,hgdiobj);
4092                 GDI_UNLOCK(); // gdi_lock
4093                 InvalidateRect(hPanelWnd, &(MPanel.rcMisc), FALSE);
4094    }
4095    if(MPanel.UpdateFlag & MP_UPDATE_MESSAGE){
4096                 HGDIOBJ hgdiobj;
4097                 GDI_LOCK(); // gdi_lock
4098                 hgdiobj = SelectObject(MPanel.hmdc,MPanel.hFontMessage);
4099                 SetTextColor(MPanel.hmdc,MPanel.FGColor);
4100                 SetBkColor(MPanel.hmdc,MPanel.BGColor);
4101                 SetTextAlign(MPanel.hmdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
4102                 switch ( MPanelMessageData.curmode ) {
4103                 case 0:
4104                         ExtTextOut(MPanel.hmdc,MPanel.rcMessage.left,MPanel.rcMessage.top,
4105                                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMessage),
4106                         MPanelMessageData.buff,strlen(MPanelMessageData.buff),NULL);
4107                 case 1:
4108                         ExtTextOut(MPanel.hmdc,MPanel.rcMessage.left,MPanel.rcMessage.top,
4109                                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMessage),
4110                         MPanelMessageData.buff,strlen(MPanelMessageData.buff),NULL);
4111 //                      ExtTextOut(MPanel.hmdc,MPanel.rcMessage.left-(MPanel.rcMessage.bottom-MPanel.rcMessage.top)*2,
4112 //                              MPanel.rcMessage.top, ETO_CLIPPED       | ETO_OPAQUE,&(MPanel.rcMessage),
4113 //                      MPanelMessageData.buff,strlen(MPanelMessageData.buff),NULL);
4114                 case 2:
4115                         ExtTextOut(MPanel.hmdc,MPanel.rcMessage.left,MPanel.rcMessage.top,
4116                                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMessage),
4117                         MPanelMessageData.buff,strlen(MPanelMessageData.buff),NULL);
4118                 case -1:
4119                 default:
4120                         ExtTextOut(MPanel.hmdc,MPanel.rcMessage.left,MPanel.rcMessage.top,
4121                                 ETO_CLIPPED     | ETO_OPAQUE,&(MPanel.rcMessage),
4122                         MPanelMessageData.buff,strlen(MPanelMessageData.buff),NULL);
4123                 }
4124                 if((HGDIOBJ)hgdiobj!=(HGDIOBJ)NULL && (HGDIOBJ)hgdiobj!=(HGDIOBJ)GDI_ERROR)
4125                         SelectObject(MPanel.hmdc,hgdiobj);
4126                 GDI_UNLOCK(); // gdi_lock
4127                 InvalidateRect(hPanelWnd, &(MPanel.rcMessage), FALSE);
4128    }
4129         if(MPanel.UpdateFlag==MP_UPDATE_ALL)
4130                 InvalidateRect(hPanelWnd, NULL, FALSE);
4131         MPanel.UpdateFlag = MP_UPDATE_NONE;
4132 }
4133
4134 static void MPanelPaintDo(void)
4135 {
4136         RECT rc;
4137         if ( GetUpdateRect(MPanel.hwnd, &rc, FALSE) ) {
4138                 PAINTSTRUCT ps;
4139                 HDC hdc;
4140                 GDI_LOCK(); // gdi_lock
4141                 hdc = BeginPaint(MPanel.hwnd, &ps);
4142                 BitBlt(hdc,rc.left,rc.top,rc.right,rc.bottom,MPanel.hmdc,rc.left,rc.top,SRCCOPY);
4143                 EndPaint(MPanel.hwnd, &ps);
4144                 GDI_UNLOCK(); // gdi_lock
4145         }
4146 }
4147
4148 // \95`\89æ
4149 void MPanelPaint(void)
4150 {
4151         UpdateWindow(hPanelWnd);
4152 }
4153
4154 // \8a®\91S\95`\89æ
4155 void MPanelPaintAll(void)
4156 {
4157         InvalidateRect(hPanelWnd, NULL, FALSE);
4158         MPanelPaint();
4159 }
4160
4161 // \83p\83l\83\8b\8d\\91¢\91Ì\82ð\8c³\82É\8a®\91S\8dX\90V\82ð\82·\82é\81B
4162 void MPanelUpdateAll(void)
4163 {
4164         if(!MPanelOK)
4165                 return;
4166         MPanel.UpdateFlag = MP_UPDATE_ALL;
4167         MPanelUpdate();
4168 }
4169
4170 // PanelInfo \8d\\91¢\91Ì\82ð\93Ç\82Ý\8d\9e\82ñ\82Å\83p\83l\83\8b\8d\\91¢\91Ì\82Ö\93K\97p\82·\82é\81B
4171 // flag \82Í\8b­\90§\8dX\90V\82·\82é\81B
4172 void MPanelReadPanelInfo(int flag)
4173 {
4174         if(!MPanelOK)
4175                 return;
4176         if(!PInfoOK)
4177         return;
4178
4179         if(!Panel->changed && !flag)
4180         return;
4181
4182         if(flag
4183         ||      MPanel.CurTime_s != Panel->cur_time_s
4184 //    || MPanel.CurTime_ss != Panel->cur_time_ss
4185                 || MPanel.CurTime_m != Panel->cur_time_m
4186                 || MPanel.CurTime_h != Panel->cur_time_h
4187                 || MPanel.TotalTime_s != Panel->total_time_s
4188 //              || MPanel.TotalTime_ss != Panel->total_time_ss
4189                 || MPanel.TotalTime_m != Panel->total_time_m
4190                 || MPanel.TotalTime_h != Panel->total_time_h
4191         ){
4192                 MPanel.CurTime_h = Panel->cur_time_h;
4193                 MPanel.CurTime_m = Panel->cur_time_m;
4194                 MPanel.CurTime_s = Panel->cur_time_s;
4195                 MPanel.CurTime_ss = Panel->cur_time_ss;
4196                 MPanel.TotalTime_h = Panel->total_time_h;
4197                 MPanel.TotalTime_m = Panel->total_time_m;
4198                 MPanel.TotalTime_s = Panel->total_time_s;
4199 //              MPanel.TotalTime_ss = Panel->total_time_ss;
4200                 RANGE(MPanel.CurTime_h,0,99);
4201       RANGE(MPanel.TotalTime_h,0,99);
4202         MPanel.UpdateFlag |=    MP_UPDATE_TIME;
4203         }
4204         if(flag || MPanel.MaxVoices != Panel->voices){
4205                 MPanel.MaxVoices = Panel->voices;
4206         MPanel.UpdateFlag |=    MP_UPDATE_VOICES;
4207    }
4208         if(flag || MPanel.CurVoices != Panel->cur_voices){
4209                 MPanel.CurVoices = Panel->cur_voices;
4210         MPanel.UpdateFlag |=    MP_UPDATE_VOICES;
4211    }
4212 ///r
4213         if(flag || MPanel.MVolume != output_amplification){
4214                 MPanel.MVolume = output_amplification;
4215         MPanel.UpdateFlag |=    MP_UPDATE_MVOLUME;
4216    }
4217         if(flag || MPanel.Rate != play_mode->rate){
4218                 MPanel.Rate = play_mode->rate;
4219         MPanel.UpdateFlag |=    MP_UPDATE_RATE;
4220    }
4221         if (flag || MPanel.Meas != Panel->meas) {
4222                 MPanel.Meas = Panel->meas;
4223                 MPanel.UpdateFlag |= MP_UPDATE_METRONOME;
4224         }
4225         if (flag || MPanel.Beat != Panel->beat) {
4226                 MPanel.Beat = Panel->beat;
4227                 MPanel.UpdateFlag |= MP_UPDATE_METRONOME;
4228         }
4229         if (flag || MPanel.Keysig != Panel->keysig) {
4230                 strcpy(MPanel.Keysig, Panel->keysig);
4231                 MPanel.UpdateFlag |= MP_UPDATE_KEYSIG;
4232         }
4233         if (flag || MPanel.Key_offset != Panel->key_offset) {
4234                 MPanel.Key_offset = Panel->key_offset;
4235                 MPanel.UpdateFlag |= MP_UPDATE_KEYSIG;
4236         }
4237         if (flag || MPanel.Tempo != Panel->tempo) {
4238                 MPanel.Tempo = Panel->tempo;
4239                 MPanel.UpdateFlag |= MP_UPDATE_TEMPO;
4240         }
4241         if (flag || MPanel.Tempo_ratio != Panel->tempo_ratio) {
4242                 MPanel.Tempo_ratio = Panel->tempo_ratio;
4243                 MPanel.UpdateFlag |= MP_UPDATE_TEMPO;
4244         }
4245 ///r
4246 /*
4247         w32g_get_playlist_index(&cur_pl_num, &playlist_num, NULL);
4248         if(playlist_num > 0)
4249                 cur_pl_num++;
4250         if(flag || MPanel.PlaylistNum != cur_pl_num){
4251                 MPanel.PlaylistNum = cur_pl_num;
4252         MPanel.UpdateFlag |=    MP_UPDATE_PLAYLIST;
4253    }
4254         if(flag || MPanel.PlaylistMax != playlist_num){
4255                 MPanel.PlaylistMax = playlist_num;
4256         MPanel.UpdateFlag |=    MP_UPDATE_PLAYLIST;
4257    }
4258 */
4259         {
4260                 int rate;
4261                 float devsiz,filled;
4262                 devsiz = aq_get_dev_queuesize();
4263                 filled = aq_filled() + aq_soft_filled();
4264                 rate = devsiz <= 0 ?  0 : (int)(filled / devsiz * 100 + 0.5); // 
4265                 if(rate > 9999)
4266                         rate = 9999;
4267                 if(flag || MPanel.aq_ratio != rate){
4268                         MPanel.rq_flag[0] = reduce_quality_flag ? 'Q' : ' ';
4269                         MPanel.rv_flag[0] = reduce_voice_flag ? 'V' : ' ';
4270                         MPanel.rp_flag[0] = reduce_polyphony_flag ? 'P' : ' ';
4271                         MPanel.aq_ratio = rate;
4272                 MPanel.UpdateFlag |=    MP_UPDATE_AQ_RATIO;
4273                 }
4274         }
4275
4276         if(flag || MPanel.play_system_mode != play_system_mode){
4277                 MPanel.play_system_mode = play_system_mode;
4278         MPanel.UpdateFlag |=    MP_UPDATE_MISC;
4279    }
4280         if(current_file_info!=NULL){
4281         if(flag || MPanel.current_file_info_file_type != current_file_info->file_type){
4282       MPanel.current_file_info_file_type = current_file_info->file_type;
4283         MPanel.UpdateFlag |=    MP_UPDATE_MISC;
4284    }
4285         if(flag || MPanel.current_file_info_max_channel != current_file_info->max_channel){
4286       MPanel.current_file_info_max_channel = current_file_info->max_channel;
4287         MPanel.UpdateFlag |=    MP_UPDATE_MISC;
4288    }
4289    }
4290 }
4291
4292 void MPanelStartLoad(char *filename)
4293 {
4294     strncpy((char *)MPanel.File, filename, MP_FILE_MAX);
4295     MPanel.UpdateFlag |= MP_UPDATE_FILE;
4296     MPanelUpdate();
4297 }
4298
4299 void MPanelMessageInit(void)
4300 {
4301         int width = (MPanel.rcMessage.bottom - MPanel.rcMessage.top + 1) / 2;
4302         MPanelMessageData.len = (MPanel.rcMessage.right - MPanel.rcMessage.left) / width;
4303         MPanelMessageClearAll();
4304 }
4305
4306 // sec \95b\82Å message \82ð\97¬\82·\81B
4307 // mode 0: sec \95b\82¾\82¯ message \82ð\95\\8e¦\81B\83f\83t\83H\83\8b\83g\81B
4308 // mode 1: sec \95b\82Ì\8aÔ\82É message \82ð\89E\82©\82ç\8d\82É\97¬\82·\81B
4309 // mode 2: sec \95b\82Ì\8aÔ\82É messege \82ð\95\\8e¦\81B\83|\83C\83\93\83^\82ð\8d\82©\82ç\89E\82É\88Ú\82·\81B\83|\83C\83\93\83^\82ð\8b«\8aE\82É\90F\82ð\95Ï\82¦\82é\81B
4310 void MPanelMessageAdd(char *message, int msec, int mode)
4311 {
4312         if ( MPanelMessageData.nextmode >= 0 ) {
4313                 MPanelMessageNext();
4314                 strncpy(MPanelMessageData.nextbuff,message,sizeof(MPanelMessageData.nextbuff)-1);
4315                 MPanelMessageData.nextmode = mode;
4316                 MPanelMessageData.nextmsec = msec;
4317         } else if ( MPanelMessageData.curmode >= 0 ){
4318                 strncpy(MPanelMessageData.nextbuff,message,sizeof(MPanelMessageData.nextbuff)-1);
4319                 MPanelMessageData.nextmode = mode;
4320                 MPanelMessageData.nextmsec = msec;
4321         } else {
4322                 strncpy(MPanelMessageData.nextbuff,message,sizeof(MPanelMessageData.nextbuff)-1);
4323                 MPanelMessageData.nextmode = mode;
4324                 MPanelMessageData.nextmsec = msec;
4325                 MPanelMessageNext();
4326         }
4327 }
4328 int MPanelMessageHaveMesssage(void)
4329 {
4330         if ( MPanelMessageData.curmode >= 0 || MPanelMessageData.nextmode >= 0 )
4331                 return 1;
4332         else
4333                 return 0;
4334 }
4335 void MPanelMessageClearAll(void)
4336 {
4337         MPanelMessageData.buff[0] = '\0';
4338         MPanelMessageData.curmode = -1;
4339         MPanelMessageData.nextmode = -1;
4340         MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4341 }
4342 void MPanelMessageClear(void)
4343 {
4344         MPanelMessageData.buff[0] = '\0';
4345         MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4346 }
4347 void MPanelMessageNext(void)
4348 {
4349         MPanelMessageClear();
4350         if ( MPanelMessageData.nextmode >= 0 ) {
4351                 strcpy(MPanelMessageData.curbuff,MPanelMessageData.nextbuff);
4352                 MPanelMessageData.curbuffsize = strlen(MPanelMessageData.curbuff);
4353                 MPanelMessageData.curmode = MPanelMessageData.nextmode;
4354                 MPanelMessageData.curmsec = MPanelMessageData.nextmsec;
4355                 MPanelMessageData.pointer = -1;
4356                 MPanelMessageData.nextmode = -1;
4357                 MPanelMessageData.prevtime = -1;
4358         } else {
4359                 MPanelMessageData.curmode = -1;
4360                 MPanelMessageData.prevtime = -1;
4361         }
4362         MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4363 }
4364 void MPanelMessageUpdate(void)
4365 {
4366 //      DWORD curtime = GetCurrentTime();
4367         DWORD curtime = 0;
4368         int pointer; 
4369
4370         if ( MPanelMessageData.curmode >= 0 ) {
4371                 curtime += Panel->cur_time_h; 
4372                 curtime *= 24;
4373                 curtime += Panel->cur_time_m;
4374                 curtime *= 60;
4375                 curtime += Panel->cur_time_s;
4376                 curtime *= 1000;
4377                 curtime += Panel->cur_time_ss;
4378         }
4379         switch ( MPanelMessageData.curmode ) {
4380         case 0:
4381                 if ( MPanelMessageData.prevtime == -1 ){
4382                         strcpy( MPanelMessageData.buff, MPanelMessageData.curbuff );
4383                         MPanelMessageData.prevtime = curtime;
4384                         MPanelMessageData.msec = MPanelMessageData.curmsec;
4385                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4386                 } else {
4387                         MPanelMessageData.msec -= curtime - MPanelMessageData.prevtime;
4388                         MPanelMessageData.prevtime = curtime;
4389                 }
4390                 if ( MPanelMessageData.msec <= 0 || curtime < MPanelMessageData.prevtime ) {
4391                         MPanelMessageNext();
4392                         MPanelMessageUpdate();
4393                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4394                         break;
4395                 }
4396                 break;
4397         case 1:
4398                 if ( MPanelMessageData.prevtime == -1 ){
4399                         MPanelMessageData.prevtime = curtime;
4400                         MPanelMessageData.msec = MPanelMessageData.curmsec;
4401                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4402                 } else {
4403                         MPanelMessageData.msec -= curtime - MPanelMessageData.prevtime;
4404                         MPanelMessageData.prevtime = curtime;
4405                 }
4406                 if ( MPanelMessageData.msec <= 0 || curtime < MPanelMessageData.prevtime ) {
4407                         MPanelMessageNext();
4408                         MPanelMessageUpdate();
4409                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4410                         return;
4411                 }
4412 //              pointer = MPanelMessageData.len * 4 / 5 + ( MPanelMessageData.curmsec - MPanelMessageData.msec ) / 1000 * 2;
4413                 pointer = MPanelMessageData.len - 8 + ( MPanelMessageData.curmsec - MPanelMessageData.msec ) / 1000 * 2;
4414                 pointer = (int)( pointer / 2 ) * 2;
4415                 if ( MPanelMessageData.pointer != pointer ) {
4416                         int p = MPanelMessageData.len - pointer;
4417                         MPanelMessageData.buff[0] = '\0';
4418                         MPanelMessageData.pointer = pointer;
4419                         if ( p >= 0 ) {
4420                                 memset( MPanelMessageData.buff, 0x20, p );
4421                                 MPanelMessageData.buff[p] = '\0';
4422                                 strcat( MPanelMessageData.buff, MPanelMessageData.curbuff);
4423                         } else if ( MPanelMessageData.curbuffsize + p > 0 ) { 
4424                                 strcpy( MPanelMessageData.buff, MPanelMessageData.curbuff - p);
4425                         } else {
4426                                 MPanelMessageData.buff[0] = '\0';
4427                         }
4428                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4429                 }
4430                 break;
4431         case 2:
4432                 if ( MPanelMessageData.prevtime == -1 ){
4433                         strcpy( MPanelMessageData.buff, MPanelMessageData.curbuff );
4434                         MPanelMessageData.prevtime = curtime;
4435                         MPanelMessageData.msec = MPanelMessageData.curmsec;
4436                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4437                 } else {
4438                         MPanelMessageData.msec -= curtime - MPanelMessageData.prevtime;
4439                         MPanelMessageData.prevtime = curtime;
4440                 }
4441                 if ( MPanelMessageData.msec <= 0 || curtime < MPanelMessageData.prevtime ) {
4442                         MPanelMessageNext();
4443                         MPanelMessageUpdate();
4444                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4445                         break;
4446                 }
4447                 pointer = ( MPanelMessageData.len + MPanelMessageData.curbuffsize ) * ( MPanelMessageData.curmsec - MPanelMessageData.msec ) / MPanelMessageData.curmsec;
4448                 if ( MPanelMessageData.pointer != pointer ) {
4449                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4450                 }
4451                 break;
4452         case 3:
4453                 if ( MPanelMessageData.prevtime == -1 ){
4454                         MPanelMessageData.prevtime = curtime;
4455                         MPanelMessageData.msec = MPanelMessageData.curmsec;
4456                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4457                 } else {
4458                         MPanelMessageData.msec -= curtime - MPanelMessageData.prevtime;
4459                         MPanelMessageData.prevtime = curtime;
4460                 }
4461                 if ( MPanelMessageData.msec <= 0 || curtime < MPanelMessageData.prevtime ) {
4462                         MPanelMessageNext();
4463                         MPanelMessageUpdate();
4464                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4465                         return;
4466                 }
4467                 pointer = MPanelMessageData.len * 3 / 4 + ( MPanelMessageData.len / 4 + MPanelMessageData.curbuffsize ) * ( MPanelMessageData.curmsec - MPanelMessageData.msec ) / MPanelMessageData.curmsec;
4468                 pointer = ((int)(pointer / 2)) * 2;
4469                 if ( MPanelMessageData.pointer != pointer ) {
4470                         int p = MPanelMessageData.len - pointer;
4471                         MPanelMessageData.buff[0] = '\0';
4472                         MPanelMessageData.pointer = pointer;
4473                         if ( p >= 0 ) {
4474                                 memset( MPanelMessageData.buff, 0x20, p );
4475                                 MPanelMessageData.buff[p] = '\0';
4476                                 strcat( MPanelMessageData.buff, MPanelMessageData.curbuff);
4477                         } else if ( MPanelMessageData.curbuffsize + p > 0 ) { 
4478                                 strcpy( MPanelMessageData.buff, MPanelMessageData.curbuff - p);
4479                         } else {
4480                                 MPanelMessageData.buff[0] = '\0';
4481                         }
4482                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4483                 }
4484                 break;
4485         case 4:
4486                 if ( MPanelMessageData.prevtime == -1 ){
4487                         MPanelMessageData.prevtime = curtime;
4488 #define MPANELMESSAGE_MODE2_SLEEPMSEC 1000
4489                         if ( MPanelMessageData.curmsec < MPANELMESSAGE_MODE2_SLEEPMSEC * 2 ) {
4490                                 MPanelMessageData.curmsec = MPANELMESSAGE_MODE2_SLEEPMSEC * 2;
4491                         }
4492                         MPanelMessageData.msec = MPanelMessageData.curmsec;
4493                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4494                 } else {
4495                         MPanelMessageData.msec -= curtime - MPanelMessageData.prevtime;
4496                         MPanelMessageData.prevtime = curtime;
4497                 }
4498                 if ( MPanelMessageData.msec <= 0 || curtime < MPanelMessageData.prevtime ) {
4499                         MPanelMessageNext();
4500                         MPanelMessageUpdate();
4501                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4502                         return;
4503                 }
4504                 if ( MPanelMessageData.curmsec - MPanelMessageData.msec <= MPANELMESSAGE_MODE2_SLEEPMSEC ) {
4505                         pointer = 0;
4506                 } else {
4507                         pointer = MPanelMessageData.curbuffsize * ( MPanelMessageData.curmsec - MPanelMessageData.msec - MPANELMESSAGE_MODE2_SLEEPMSEC ) / ( MPanelMessageData.curmsec - MPANELMESSAGE_MODE2_SLEEPMSEC );
4508                 }
4509                 pointer = ((int)(pointer / 2)) * 2;
4510                 if ( MPanelMessageData.pointer != pointer ) {
4511                         MPanelMessageData.buff[0] = '\0';
4512                         MPanelMessageData.pointer = pointer;
4513                         if ( pointer < MPanelMessageData.curbuffsize ) { 
4514                                 strcpy( MPanelMessageData.buff, MPanelMessageData.curbuff + pointer );
4515                         } else {
4516                                 MPanelMessageData.buff[0] = '\0';
4517                         }
4518                 MPanel.UpdateFlag |= MP_UPDATE_MESSAGE;
4519                 }
4520                 break;
4521         case -1:
4522         default:
4523 //              MPanelMessageData.buff[0] = '\0';
4524                 break;
4525         }
4526 }
4527
4528
4529
4530
4531 // ----------------------------------------------------------------------------
4532 // Misc. Controls
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544 // ----------------------------------------------------------------------------
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554 // ****************************************************************************
4555 // Version Window
4556
4557 static void VersionWnd(HWND hParentWnd)
4558 {
4559         char VersionText[2024];
4560   sprintf(VersionText,
4561 "TiMidity++ %s%s %s" NLS NLS
4562 "TiMidity-0.2i by Tuukka Toivonen <tt@cgs.fi>." NLS
4563 "TiMidity Win32 version by Davide Moretti <dave@rimini.com>." NLS
4564 "TiMidity Windows 95 port by Nicolas Witczak." NLS
4565 "TiMidity Win32 GUI by Daisuke Aoki <dai@y7.net>." NLS
4566 " Japanese menu, dialog, etc by Saito <timidity@flashmail.com>." NLS
4567 "TiMidity++ by Masanao Izumo <mo@goice.co.jp>." NLS
4568 ,(strcmp(timidity_version, "current")) ? "version " : "", timidity_version, arch_string
4569 );
4570         MessageBox(hParentWnd, VersionText, "Version", MB_OK);
4571 }
4572
4573 static void TiMidityWnd(HWND hParentWnd)
4574 {
4575         char TiMidityText[2024];
4576   sprintf(TiMidityText,
4577 " TiMidity++ %s%s -- MIDI to WAVE converter and player" NLS
4578 " Copyright (C) 1999-2018 Masanao Izumo <iz@onicos.co.jp>" NLS
4579 " Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>" NLS
4580 NLS
4581 " Win32 version by Davide Moretti <dmoretti@iper.net>" NLS
4582 " GUI by Daisuke Aoki <dai@y7.net>." NLS
4583 " Modified by Masanao Izumo <mo@goice.co.jp>." NLS
4584 NLS
4585 " This program is free software; you can redistribute it and/or modify" NLS
4586 " it under the terms of the GNU General Public License as published by" NLS
4587 " the Free Software Foundation; either version 2 of the License, or" NLS
4588 " (at your option) any later version." NLS
4589 NLS
4590 " This program is distributed in the hope that it will be useful," NLS
4591 " but WITHOUT ANY WARRANTY; without even the implied warranty of"NLS
4592 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" NLS
4593 " GNU General Public License for more details." NLS
4594 NLS
4595 " You should have received a copy of the GNU General Public License" NLS
4596 " along with this program; if not, write to the Free Software" NLS
4597 " Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA" NLS
4598 ,
4599 (strcmp(timidity_version, "current")) ? "version " : "", timidity_version, arch_string
4600         );
4601         MessageBox(hParentWnd, TiMidityText, "TiMidity++", MB_OK);
4602 }
4603
4604 static void SupplementWnd(HWND hParentWnd)
4605 {
4606         char SupplementText[2024];
4607   sprintf(SupplementText,
4608 "GS is a registered trademark of Roland Corporation. " NLS
4609 "XG is a registered trademark of Yamaha Corporation. " NLS );
4610           MessageBox(hParentWnd, SupplementText, "Supplement", MB_OK);
4611 }
4612
4613
4614 // ****************************************************************************
4615
4616 #ifdef W32GUI_DEBUG
4617 void TiMidityHeapCheck(void)
4618 {
4619         HANDLE *ProcessHeaps = NULL;
4620    DWORD dwNumberOfHeaps;
4621         DWORD dw = 10;
4622    int i;
4623    PrintfDebugWnd("\n[Heaps Check Start]\n");
4624         if(GetProcessHeap()!=NULL)
4625         if(HeapValidate(GetProcessHeap(),0,NULL)==TRUE)
4626                 PrintfDebugWnd("Process Heap is Valid\n");
4627         else
4628                 PrintfDebugWnd("Process Heap is Invalid\n");
4629    ProcessHeaps = (HANDLE *)realloc(ProcessHeaps,sizeof(HANDLE)*dw);
4630    dwNumberOfHeaps = GetProcessHeaps(dw, ProcessHeaps);
4631    if(dw<dwNumberOfHeaps){
4632                 dw = dwNumberOfHeaps;
4633            ProcessHeaps = (HANDLE *)realloc(ProcessHeaps,sizeof(HANDLE)*dw);
4634         dwNumberOfHeaps = GetProcessHeaps(dw, ProcessHeaps);
4635    }
4636    PrintfDebugWnd("NumberOfHeaps=%ld\n",(int)dwNumberOfHeaps);
4637         for(i=0;i<(int)dwNumberOfHeaps;i++){
4638         if(HeapValidate(ProcessHeaps[i],0,NULL)==TRUE)
4639                 PrintfDebugWnd("Heap %d is Valid\n",i+1);
4640       else
4641                 PrintfDebugWnd("Heap %d is Invalid\n",i+1);
4642    }
4643    PrintfDebugWnd("[Heaps Check End]\n\n");
4644         safe_free(ProcessHeaps);
4645 }
4646 #endif
4647
4648 void TiMidityVariablesCheck(void)
4649 {
4650 #if 0
4651 // player_status
4652         PrintfDebugWnd("[player_status]\n");
4653         PrintfDebugWnd("player_status=%ld\n",player_status);
4654         switch(player_status){
4655         case PLAYERSTATUS_NONE:
4656         PrintfDebugWnd("player_status=PLAYERSTATUS_NONE\n");
4657         break;
4658         case PLAYERSTATUS_STOP:
4659         PrintfDebugWnd("player_status=PLAYERSTATUS_STOP\n");
4660         break;
4661         case PLAYERSTATUS_PAUSE:
4662         PrintfDebugWnd("player_status=PLAYERSTATUS_PAUSE\n");
4663         break;
4664         case PLAYERSTATUS_PLAY:
4665         PrintfDebugWnd("player_status=PLAYERSTATUS_PLAY\n");
4666         break;
4667         case PLAYERSTATUS_PLAYSTART:
4668         PrintfDebugWnd("player_status=PLAYERSTATUS_PLAYSTART\n");
4669         break;
4670         case PLAYERSTATUS_DEMANDPLAY:
4671         PrintfDebugWnd("player_status=PLAYERSTATUS_DEMANDPLAY\n");
4672         break;
4673         case PLAYERSTATUS_PLAYEND:
4674         PrintfDebugWnd("player_status=PLAYERSTATUS_PLAYEND\n");
4675         break;
4676         case PLAYERSTATUS_PLAYERROREND:
4677         PrintfDebugWnd("player_status=PLAYERSTATUS_PLAYERROREND\n");
4678         break;
4679         case PLAYERSTATUS_QUIT:
4680         PrintfDebugWnd("player_status=PLAYERSTATUS_QUIT\n");
4681         break;
4682         case PLAYERSTATUS_ERROR:
4683         PrintfDebugWnd("player_status=PLAYERSTATUS_ERROR\n");
4684         break;
4685         case PLAYERSTATUS_FORCED_EXIT:
4686         PrintfDebugWnd("player_status=PLAYERSTATUS_FORCED_EXIT\n");
4687         break;
4688         default:
4689    break;
4690    }
4691 #endif
4692 }
4693
4694 extern int32 test_var[10];
4695 int32 test_var[10] = {0};
4696
4697
4698 // ****************************************************************************
4699 // Debug Window
4700 #ifdef W32GUI_DEBUG
4701
4702 BOOL CALLBACK DebugWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
4703 void InitDebugEditWnd(HWND hParentWnd);
4704
4705 void InitDebugWnd(HWND hParentWnd)
4706 {
4707         hDebugWnd = CreateDialog
4708                         (hInst,MAKEINTRESOURCE(IDD_DIALOG_DEBUG),hParentWnd,DebugWndProc);
4709         ShowWindow(hDebugWnd,SW_HIDE);
4710         UpdateWindow(hDebugWnd);
4711 }
4712
4713 BOOL CALLBACK
4714 DebugWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
4715 {
4716         switch (uMess){
4717                 case WM_INITDIALOG:
4718 //                      InitDebugEditWnd(hwnd);
4719                 hDebugEditWnd = GetDlgItem(hwnd,IDC_EDIT);
4720                 if(DebugWndFlag)
4721                         CheckDlgButton(hwnd, IDC_CHECKBOX_DEBUG_WND_VALID, 1);
4722       else
4723                         CheckDlgButton(hwnd, IDC_CHECKBOX_DEBUG_WND_VALID, 0);
4724                 TiMidityHeapCheck();
4725                         return FALSE;
4726                 case WM_DESTROY:
4727         PostQuitMessage(0);
4728                         return 0;
4729     case WM_COMMAND:
4730         switch (LOWORD(wParam)) {
4731       case IDCLOSE:
4732         ShowWindow(hwnd, SW_HIDE);
4733          break;
4734       case IDCLEAR:
4735                         ClearDebugWnd();
4736          break;
4737                         case IDC_CHECKBOX_DEBUG_WND_VALID:
4738                                 if(IsDlgButtonChecked(hwnd,IDC_CHECKBOX_DEBUG_WND_VALID))
4739                                         DebugWndFlag = 1;
4740                                 else
4741                                         DebugWndFlag = 0;
4742          break;
4743       case IDC_BUTTON_EXITPROCESS:
4744                 ExitProcess(0);
4745                         return 0;
4746       case IDC_BUTTON_EXIT:
4747                 return DestroyWindow(hwnd);
4748       case IDC_BUTTON_HEAP_CHECK:
4749                         TiMidityHeapCheck();
4750                 break;
4751       case IDC_BUTTON_VARIABLES_CHECK:
4752                         TiMidityVariablesCheck();
4753                 break;
4754         case IDC_EDIT_VAR0:
4755         case IDC_EDIT_VAR1:
4756         case IDC_EDIT_VAR2:
4757         case IDC_EDIT_VAR3:
4758         case IDC_EDIT_VAR4:
4759         case IDC_EDIT_VAR5:
4760         case IDC_EDIT_VAR6:
4761         case IDC_EDIT_VAR7:
4762         case IDC_EDIT_VAR8:
4763         case IDC_EDIT_VAR9:
4764         break;
4765         case IDC_BUTTON_VAR_ENTER:
4766         {
4767                 int i;          
4768                 for(i=0; i<10;i++)
4769                         test_var[i] = GetDlgItemInt(hwnd, IDC_EDIT_VAR0 + i, NULL, TRUE);
4770         }
4771                 break;
4772       default:
4773                         break;
4774       }
4775         switch (HIWORD(wParam)) {
4776                 case EN_ERRSPACE:
4777         ClearConsoleWnd();
4778 //              PutsConsoleWnd("### EN_ERRSPACE -> Clear! ###\n");
4779                         break;
4780                 default:
4781         break;
4782       }
4783         break;
4784     case WM_SIZE:
4785 //      GetClientRect(hDebugWnd, &rc);
4786 //      MoveWindow(hDebugEditWnd, rc.left, rc.top,rc.right, rc.bottom - 30,TRUE);
4787             return FALSE;
4788                 case WM_CLOSE:
4789                                         ShowWindow(hDebugWnd, SW_HIDE);
4790           break;
4791     default:
4792         return FALSE;
4793         }
4794         return FALSE;
4795 }
4796
4797 #if 0
4798 void InitDebugEditWnd(HWND hParentWnd)
4799 {
4800   RECT rc;
4801         GetClientRect(hParentWnd, &rc);
4802         hDebugEditWnd = CreateWindowEx(
4803         WS_EX_CLIENTEDGE|WS_EX_TOOLWINDOW|WS_EX_DLGMODALFRAME,
4804         "EDIT","",
4805                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOHSCROLL | WS_HSCROLL
4806     |ES_READONLY | ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL ,
4807 //              0,0,rc.right, rc.bottom - 30,hParentWnd,NULL,hInst,NULL);
4808         0,0,100,100,hParentWnd,NULL,hInst,NULL);
4809         SendMessage(hDebugEditWnd, EM_SETLIMITTEXT, (WPARAM)1024*640, 0);
4810 //  SendMessage(hDebugEditWnd, WM_PAINT, 0, 0);
4811         GetClientRect(hParentWnd, &rc);
4812         MoveWindow(hDebugEditWnd,rc.left,rc.top,rc.right,rc.bottom-30,TRUE);
4813         ClearDebugWnd();
4814         ShowWindow(hDebugEditWnd,SW_SHOW);
4815         UpdateWindow(hDebugEditWnd);
4816 }
4817 #endif
4818
4819 void PutsDebugWnd(char *str)
4820 {
4821         if(!IsWindow(hDebugEditWnd) || !DebugWndFlag)
4822                 return;
4823         PutsEditCtlWnd(hDebugEditWnd,str);
4824 }
4825
4826 void PrintfDebugWnd(char *fmt, ...)
4827 {
4828         va_list ap;
4829         if(!IsWindow(hDebugEditWnd) || !DebugWndFlag)
4830                 return;
4831         va_start(ap, fmt);
4832         VprintfEditCtlWnd(hDebugEditWnd,fmt,ap);
4833         va_end(ap);
4834 }
4835
4836 void ClearDebugWnd(void)
4837 {
4838         if(!IsWindow(hDebugEditWnd))
4839                 return;
4840         ClearEditCtlWnd(hDebugEditWnd);
4841 }
4842 #endif
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865 // ****************************************************************************
4866 // Main Thread
4867
4868 extern HWND hListSearchWnd;
4869 extern void HideListSearch(void);
4870
4871 #ifndef __BORLANDC__
4872 DWORD volatile dwMainThreadId = 0;
4873 #endif
4874
4875 void WINAPI MainThread(void *arglist)
4876 {
4877 #ifdef __BORLANDC__
4878         DWORD volatile dwMainThreadId = 0;
4879 #endif
4880     MSG msg;
4881
4882         ThreadNumMax++;
4883
4884         dwMainThreadId = GetCurrentThreadId ();
4885 #ifdef W32GUI_DEBUG
4886         PrintfDebugWnd("(*/%d)MainThread : Start.\n",ThreadNumMax);
4887 #endif
4888 #ifdef USE_THREADTIMES
4889         ThreadTimesAddThread(hMainThread,"MainThread");
4890 #endif
4891 // Thread priority
4892 //      SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL);
4893         SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
4894 //      SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
4895
4896
4897     InitStartWnd(SW_HIDE);
4898
4899     w32g_wait_for_init = 0;
4900
4901 // message loop for the application
4902         while( GetMessage(&msg,NULL,0,0) ){
4903 //              HandleFastSearch(msg);
4904 //PrintfDebugWnd("H%lu M%lu WP%lu LP%lu T%lu x%d y%d\n",
4905 //      msg.hwnd, msg.message, msg.wParam, msg.lParam, msg.time, msg.pt.x, msg.pt.y);
4906 #if 1
4907                 // ESC \82Å\91\8b\82ð\95Â\82\82é\81
4908                 if ( msg.message == WM_KEYDOWN && (int)msg.wParam == VK_ESCAPE ) {
4909                         if ( msg.hwnd == hConsoleWnd || IsChild ( hConsoleWnd, msg.hwnd ) ) {
4910                                  ToggleSubWindow(hConsoleWnd);
4911                         } else if ( msg.hwnd == hDocWnd || IsChild ( hDocWnd, msg.hwnd ) ) {
4912                                  ToggleSubWindow(hDocWnd);
4913                         } else if ( msg.hwnd == hWrdWnd || IsChild ( hWrdWnd, msg.hwnd ) ) {
4914                                  ToggleSubWindow(hWrdWnd);
4915                         } else if ( msg.hwnd == hListWnd || IsChild ( hListWnd, msg.hwnd ) ) {
4916                                  ToggleSubWindow(hListWnd);
4917                         } else if ( msg.hwnd == hListSearchWnd || IsChild ( hListSearchWnd, msg.hwnd ) ) {
4918                                 HideListSearch();
4919                         } else if ( msg.hwnd == hTracerWnd || IsChild ( hTracerWnd, msg.hwnd ) ) {
4920                                 ToggleSubWindow(hTracerWnd);
4921                         } else if ( msg.hwnd == hSoundSpecWnd || IsChild ( hSoundSpecWnd, msg.hwnd ) ) {
4922                                 ToggleSubWindow(hSoundSpecWnd);
4923                         }
4924                 }
4925 #endif
4926                 TranslateMessage(&msg);
4927                 DispatchMessage(&msg);
4928         }
4929
4930 #ifdef W32GUI_DEBUG
4931         Sleep(200);
4932         PrintfDebugWnd("w32gui_main: DebugWndExit\n");
4933 //   MessageBox(NULL, "Exit!","Exit!",MB_OK);
4934         if(hDebugWnd!=NULL)
4935                 for(;;){
4936                         if(!DebugThreadExit){
4937                         SendMessage(hDebugWnd,WM_COMMAND,(WPARAM)IDC_BUTTON_EXIT,0);
4938                                 Sleep(100);
4939          } else
4940                 break;
4941       }
4942 #endif
4943         if(!w32g_restart_gui_flag)
4944         {
4945                 OnExitReady();
4946                 w32g_send_rc(RC_QUIT, 0);
4947         }
4948         crt_endthread();
4949 }
4950
4951
4952
4953
4954 // **************************************************************************
4955 // Misc Dialog
4956 #if FILEPATH_MAX < 16536
4957 #define DialogMaxFileName 16536
4958 #else
4959 #define DialogMaxFileName FILEPATH_MAX
4960 #endif
4961 static char DialogFileNameBuff[DialogMaxFileName];
4962 static char *DlgFileOpen(HWND hwnd, const char *title, const char *filter, const char *dir)
4963 {
4964         OPENFILENAME ofn;
4965     memset(DialogFileNameBuff, 0, sizeof(DialogFileNameBuff));
4966         memset(&ofn, 0, sizeof(OPENFILENAME));
4967         ofn.lStructSize = sizeof(OPENFILENAME);
4968         ofn.hwndOwner = hwnd;
4969         ofn.hInstance = hInst ;
4970         ofn.lpstrFilter = filter;
4971         ofn.lpstrCustomFilter = NULL;
4972         ofn.nMaxCustFilter = 0;
4973         ofn.nFilterIndex = 1 ;
4974         ofn.lpstrFile = DialogFileNameBuff;
4975         ofn.nMaxFile = sizeof(DialogFileNameBuff) / sizeof(DialogFileNameBuff[0]);
4976         ofn.lpstrFileTitle = 0;
4977         ofn.nMaxFileTitle = 0;
4978         ofn.lpstrInitialDir     = dir;
4979         ofn.lpstrTitle = title;
4980         ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST
4981                 | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_READONLY;
4982         ofn.lpstrDefExt = 0;
4983         ofn.lCustData = 0;
4984         ofn.lpfnHook = 0;
4985         ofn.lpTemplateName= 0;
4986
4987         if(GetOpenFileName(&ofn)==TRUE)
4988                 return DialogFileNameBuff;
4989         else
4990                 return NULL;
4991 }
4992
4993 static void DlgMidiFileOpen(HWND hwnd)
4994 {
4995     char *dir, *file;
4996     const char *filter;
4997     const char *filter_en = "timidity file\0*.mid;*.smf;*.rcp;*.r36;*.g18;*.g36;*.rmi;*.mod;*.xm;*.s3m;*.it;*.669;*.amf;*.dsm;*.far;*.gdm;*.imf;*.med;*.mtm;*.stm;*.stx;*.ult;*.uni;*.lzh;*.zip;*.gz;*.pls;*.m3u;*.asx\0"
4998                 "midi file\0*.mid;*.midi;*.smf;*.rmi\0"
4999                 "rcp file\0*.rcp;*.r36;*.g18;*.g36\0"
5000                 "mod file\0*.mod;*.xm;*.s3m;*.it;*.669;*.amf;*.dsm;*.far;*.gdm;*.imf;*.med;*.mtm;*.stm;*.stx;*.ult;*.uni\0"
5001                 "archive file\0*.lzh;*.zip;*.gz\0"
5002                 "playlist file\0*.pls;*.m3u;*.asx\0"
5003                 "all files\0*.*\0"
5004                 "\0\0";
5005     const char *filter_jp = "Timidity \83T\83|\81[\83g\8dÏ\82Ý\83t\83@\83C\83\8b\0*.mid;*.smf;*.rcp;*.r36;*.g18;*.g36;*.rmi;*.mod;*.xm;*.s3m;*.it;*.669;*.amf;*.dsm;*.far;*.gdm;*.imf;*.med;*.mtm;*.stm;*.stx;*.ult;*.uni;*.lzh;*.zip;*.gz;*.pls;*.m3u;*.asx\0"
5006                 "SMF/RMID (*.mid;*.midi;*.smf;*.rmi)\0*.mid;*.midi;*.smf;*.rmi\0"
5007                 "RCP (*.rcp;*.r36;*.g18;*.g36)\0*.rcp;*.r36;*.g18;*.g36\0"
5008                 "MOD (*.mod;*.xm;*.s3m;*.it;*.669;*.amf;*.dsm;*.far;*.gdm;*.imf;*.med;*.mtm;*.stm;*.stx;*.ult;*.uni)\0*.mod;*.xm;*.s3m;*.it;*.669;*.amf;*.dsm;*.far;*.gdm;*.imf;*.med;*.mtm;*.stm;*.stx;*.ult;*.uni\0"
5009                 "\88³\8fk\8dÏ\82Ý\83A\81[\83J\83C\83u (*.lzh;*.zip;*.gz)\0*.lzh;*.zip;*.gz\0"
5010                 "\83v\83\8c\83C\83\8a\83X\83g\83t\83@\83C\83\8b (*.pls;*.m3u;*.asx)\0*.pls;*.m3u;*.asx\0"
5011                 "\82·\82×\82Ä\82Ì\83t\83@\83C\83\8b (*.*)\0*.*\0"
5012                 "\0\0";
5013
5014     if ( PlayerLanguage == LANGUAGE_JAPANESE ) 
5015                 filter = filter_jp;
5016     else
5017                 filter = filter_en;
5018
5019     if(w32g_lock_open_file)
5020                 return;
5021
5022     if(MidiFileOpenDir[0])
5023                 dir = MidiFileOpenDir;
5024     else
5025                 dir = NULL;
5026
5027         if((file = DlgFileOpen(hwnd, NULL, filter, dir)) == NULL)
5028                 return;
5029
5030     w32g_lock_open_file = 1;
5031 #ifdef EXT_CONTROL_MAIN_THREAD
5032         w32g_ext_control_main_thread(RC_EXT_LOAD_FILE, (ptr_size_t)file);
5033 #else
5034         w32g_send_rc(RC_EXT_LOAD_FILE, (ptr_size_t)file);
5035 #endif
5036 }
5037
5038 static volatile LPITEMIDLIST itemidlist_pre = NULL;
5039 int CALLBACK DlgDirOpenBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
5040 {
5041         switch(uMsg){
5042         case BFFM_INITIALIZED:
5043                 if(itemidlist_pre)
5044                         SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)0,(LPARAM)itemidlist_pre);
5045                 break;
5046         default:
5047                 break;
5048         }
5049         return 0;
5050 }
5051
5052 static void DlgDirOpen(HWND hwnd)
5053 {
5054         static int initflag = 1;
5055         static char biBuffer[FILEPATH_MAX];
5056         static char Buffer[FILEPATH_MAX];
5057         BROWSEINFO bi;
5058         LPITEMIDLIST itemidlist;
5059
5060         if(w32g_lock_open_file)
5061             return;
5062
5063         if(initflag==1){
5064                 biBuffer[0] = '\0';
5065                 initflag = 0;
5066         }
5067         memset(&bi, 0, sizeof(bi));
5068         bi.hwndOwner = hwnd;
5069         bi.pidlRoot = NULL;
5070     bi.pszDisplayName = biBuffer;
5071         if ( PlayerLanguage == LANGUAGE_JAPANESE ) 
5072                 bi.lpszTitle = "MIDI \83t\83@\83C\83\8b\82Ì\82 \82é\83f\83B\83\8c\83N\83g\83\8a\82ð\8cä\91I\91ð\82È\82³\82ê\82Ü\82·\82æ\82¤\81B";
5073         else
5074                 bi.lpszTitle = "Select a directory with MIDI files.";
5075         bi.ulFlags = 0;
5076         bi.lpfn = DlgDirOpenBrowseCallbackProc;
5077     bi.lParam = 0;
5078     bi.iImage = 0;
5079         itemidlist = SHBrowseForFolder(&bi);
5080         if(!itemidlist)
5081                 return; /* Cancel */
5082         memset(Buffer, 0, sizeof(Buffer));
5083         SHGetPathFromIDList(itemidlist, Buffer);
5084         strncpy(biBuffer, Buffer, sizeof(Buffer) - 1);
5085         if(itemidlist_pre)
5086                 CoTaskMemFree(itemidlist_pre);
5087         itemidlist_pre = itemidlist;
5088     w32g_lock_open_file = 1;
5089         directory_form(Buffer);
5090 #ifdef EXT_CONTROL_MAIN_THREAD
5091         w32g_ext_control_main_thread(RC_EXT_LOAD_FILE, (ptr_size_t)Buffer);
5092 #else
5093         w32g_send_rc(RC_EXT_LOAD_FILE, (ptr_size_t)Buffer);
5094 #endif
5095 }
5096
5097 LRESULT CALLBACK UrlOpenWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
5098 static void DlgUrlOpen(HWND hwnd)
5099 {
5100     if(w32g_lock_open_file)
5101                 return;
5102
5103     switch(PlayerLanguage) {
5104     case LANGUAGE_JAPANESE:
5105         DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG_ONE_LINE),hwnd,UrlOpenWndProc);
5106         break;
5107     case LANGUAGE_ENGLISH:
5108     default:
5109         DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG_ONE_LINE_EN),hwnd,UrlOpenWndProc);
5110         break;
5111     }
5112 }
5113
5114 #if FILEPATH_MAX < 8192
5115 #define UrlOpenStringMax 8192
5116 #else
5117 #define UrlOpenStringMax FILEPATH_MAX
5118 #endif
5119
5120 volatile argc_argv_t UrlArgcArgv;
5121 LRESULT CALLBACK
5122 UrlOpenWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
5123 {
5124         static volatile argc_argv_t UrlArgcArgv;
5125
5126         switch (uMess){
5127         case WM_INITDIALOG:
5128                 switch(PlayerLanguage){
5129                 case LANGUAGE_JAPANESE:
5130                         SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)"URL \82ð\8aJ\82­");
5131                         SendMessage(GetDlgItem(hwnd,IDC_STATIC_HEAD),WM_SETTEXT,0,(LPARAM)"\83C\83\93\83^\81[\83l\83b\83g\82É\82 \82é\83t\83@\83C\83\8b\82Ì\83A\83h\83\8c\83X\82ð\93ü\82ê\82Ä\82­\82¾\82³\82¢\81B");
5132                         SendMessage(GetDlgItem(hwnd,IDC_STATIC_TAIL),WM_SETTEXT,0,(LPARAM)"(\97á: http, ftp, news \83v\83\8d\83g\83R\83\8b)");
5133                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_1),WM_SETTEXT,0,(LPARAM)"\89\89\91t");
5134                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_2),WM_SETTEXT,0,(LPARAM)"\83\8a\83X\83g\92Ç\89Á");
5135                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_3),WM_SETTEXT,0,(LPARAM)"\95Â\82\82é");
5136                         break;
5137                 default:
5138                 case LANGUAGE_ENGLISH:
5139                         SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)"Open Internet URL");
5140                         SendMessage(GetDlgItem(hwnd,IDC_STATIC_HEAD),WM_SETTEXT,0,(LPARAM)"Type the address of a file (on the Internet) and the player will open it for you.");
5141                         SendMessage(GetDlgItem(hwnd,IDC_STATIC_TAIL),WM_SETTEXT,0,(LPARAM)"(ex. http, ftp, news protocols)");
5142                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_1),WM_SETTEXT,0,(LPARAM)"PLAY");
5143                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_2),WM_SETTEXT,0,(LPARAM)"ADD LIST");
5144                         SendMessage(GetDlgItem(hwnd,IDC_BUTTON_3),WM_SETTEXT,0,(LPARAM)"CLOSE");
5145                         break;
5146                 }
5147                 SendDlgItemMessage(hwnd,IDC_BUTTON_1,BM_SETSTYLE,BS_DEFPUSHBUTTON,(LONG)TRUE);
5148                 SendDlgItemMessage(hwnd,IDC_BUTTON_2,BM_SETSTYLE,BS_PUSHBUTTON,(LONG)TRUE);
5149                 SendDlgItemMessage(hwnd,IDC_BUTTON_3,BM_SETSTYLE,BS_PUSHBUTTON,(LONG)TRUE);
5150                 SetFocus(GetDlgItem(hwnd,IDC_EDIT_ONE_LINE));
5151                 SendDlgItemMessage(hwnd,IDC_EDIT_ONE_LINE,EM_SETSEL,(WPARAM)0,(LPARAM)0);
5152                 SendDlgItemMessage(hwnd,IDC_EDIT_ONE_LINE,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"http://");
5153                 return TRUE;
5154         case WM_COMMAND:
5155                 switch (LOWORD(wParam)) {
5156                 case IDCLOSE:
5157                         PostMessage(hwnd,WM_CLOSE,0,0);
5158                         break;
5159                 case IDC_BUTTON_1:
5160                 {
5161                         char UrlOpenString[UrlOpenStringMax];
5162                         char **argv;
5163                         ZeroMemory(UrlOpenString, UrlOpenStringMax * sizeof(char));
5164                         SendDlgItemMessage(hwnd,IDC_EDIT_ONE_LINE,
5165                                 WM_GETTEXT,(WPARAM)(UrlOpenStringMax - 1),(LPARAM)UrlOpenString);
5166                         w32g_lock_open_file = 1;
5167                         UrlArgcArgv.argc = 1;
5168                         argv = (char **)safe_malloc((UrlArgcArgv.argc + 1) * sizeof(char *));
5169                         argv[0] = safe_strdup(UrlOpenString);
5170                         argv[1] = NULL;
5171                         UrlArgcArgv.argv = argv;
5172                         // argv, argv[0] \82Í\95Ê\82Ì\82Æ\82±\82ë\82Å\89ð\95ú\82µ\82Ä\82­\82ê\82é
5173 #ifdef EXT_CONTROL_MAIN_THREAD
5174                         w32g_ext_control_main_thread(RC_EXT_LOAD_FILES_AND_PLAY, (ptr_size_t)&UrlArgcArgv);
5175 #else
5176                         w32g_send_rc(RC_EXT_LOAD_FILES_AND_PLAY, (ptr_size_t)&UrlArgcArgv);
5177 #endif
5178                         w32g_lock_open_file = 0;
5179                         SetWindowLongPtr(hwnd,DWLP_MSGRESULT,TRUE);
5180                         EndDialog(hwnd,TRUE);
5181                 }
5182                         break;
5183                 case IDC_BUTTON_2:
5184                 {
5185                         char UrlOpenString[UrlOpenStringMax];
5186                         ZeroMemory(UrlOpenString, UrlOpenStringMax * sizeof(char));
5187                         SendDlgItemMessage(hwnd,IDC_EDIT_ONE_LINE,
5188                                 WM_GETTEXT,(WPARAM)(UrlOpenStringMax - 1),(LPARAM)UrlOpenString);
5189                         w32g_lock_open_file = 1;
5190 #ifdef EXT_CONTROL_MAIN_THREAD
5191                         w32g_ext_control_main_thread(RC_EXT_LOAD_FILE, (ptr_size_t)UrlOpenString);
5192 #else
5193                         w32g_send_rc(RC_EXT_LOAD_FILE, (ptr_size_t)UrlOpenString);
5194 #endif
5195                         SetWindowLongPtr(hwnd,DWLP_MSGRESULT,TRUE);
5196                         EndDialog(hwnd,TRUE);
5197                 }
5198                         break;
5199                 case IDC_BUTTON_3:
5200                         PostMessage(hwnd,WM_CLOSE,0,0);
5201                         break;
5202                 default:
5203                         return FALSE;
5204         }
5205                 break;
5206         case WM_CLOSE:
5207                 SetWindowLongPtr(hwnd,DWLP_MSGRESULT,FALSE);
5208                 EndDialog(hwnd,FALSE);
5209                 break;
5210         default:
5211                 return FALSE;
5212         }
5213         return FALSE;
5214 }
5215
5216 static void DlgPlaylistOpen(HWND hwnd)
5217 {
5218     char *dir, *file;
5219     char *filter =
5220                 "playlist file\0*.pls;*.m3u;*.asx\0"
5221                 "all files\0*.*\0"
5222                 "\0\0";
5223
5224     if(w32g_lock_open_file)
5225                 return;
5226
5227     if(MidiFileOpenDir[0])
5228                 dir = MidiFileOpenDir;
5229     else
5230                 dir = NULL;
5231
5232         if((file = DlgFileOpen(hwnd, NULL, filter, dir)) == NULL)
5233                 return;
5234
5235     w32g_lock_open_file = 1;
5236 #ifdef EXT_CONTROL_MAIN_THREAD
5237         w32g_ext_control_main_thread(RC_EXT_LOAD_PLAYLIST, (ptr_size_t)file);
5238 #else
5239         w32g_send_rc(RC_EXT_LOAD_PLAYLIST, (ptr_size_t)file);
5240 #endif
5241 }
5242
5243 #include <sys/stat.h> /* for stat() */
5244 static int CheckOverWrite(HWND hwnd, char *filename)
5245 {
5246         char buff[BUFSIZ];
5247         int exists;
5248
5249 #if 0
5250         FILE *fp;
5251     if((fp = fopen(filename, "r")) == NULL)
5252                 exists = 0;
5253         else
5254         {
5255                 fclose(fp);
5256                 exists = 1;
5257         }
5258 #else
5259         struct stat st;
5260         exists = (stat(filename, &st) != -1);
5261 #endif
5262
5263         if(!exists)
5264                 return 1;
5265         snprintf(buff, sizeof(buff), "%s exists. Overwrite it?", filename);
5266         return MessageBox(hwnd, buff, "Warning", MB_YESNO) == IDYES;
5267 }
5268
5269 static void DlgPlaylistSave(HWND hwnd)
5270 {
5271         OPENFILENAME ofn;
5272         static char *dir;
5273     char *filter =
5274                 "playlist file\0*.pls;*.m3u;*.asx\0"
5275                 "all files\0*.*\0"
5276                 "\0\0";
5277
5278     if(w32g_lock_open_file)
5279                 return;
5280
5281     if(MidiFileOpenDir[0])
5282                 dir = MidiFileOpenDir;
5283     else
5284                 dir = NULL;
5285
5286         memset(DialogFileNameBuff, 0, sizeof(DialogFileNameBuff));
5287         memset(&ofn, 0, sizeof(OPENFILENAME));
5288         ofn.lStructSize = sizeof(OPENFILENAME);
5289         ofn.hwndOwner = hwnd;
5290         ofn.hInstance = hInst;
5291         ofn.lpstrFilter = filter;
5292         ofn.lpstrCustomFilter = NULL;
5293         ofn.nMaxCustFilter = 0;
5294         ofn.nFilterIndex = 1 ;
5295         ofn.lpstrFile = DialogFileNameBuff;
5296         ofn.nMaxFile = sizeof(DialogFileNameBuff);
5297         ofn.lpstrFileTitle = NULL;
5298         ofn.nMaxFileTitle = 0;
5299         ofn.lpstrInitialDir     = dir;
5300         ofn.lpstrTitle  = "Save Playlist File";
5301         ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY;
5302 // ofn.lpstrDefExt = 0;
5303         ofn.lpstrDefExt = "pls";
5304         ofn.lCustData = 0;
5305         ofn.lpfnHook = 0;
5306         ofn.lpTemplateName= 0;
5307
5308         if(GetSaveFileName(&ofn) != TRUE)
5309                 return;
5310         if(!CheckOverWrite(hwnd, DialogFileNameBuff))
5311                 return;
5312     w32g_lock_open_file = 1;
5313 #ifdef EXT_CONTROL_MAIN_THREAD
5314         w32g_ext_control_main_thread(RC_EXT_SAVE_PLAYLIST, (ptr_size_t)DialogFileNameBuff);
5315 #else
5316         w32g_send_rc(RC_EXT_SAVE_PLAYLIST, (ptr_size_t)DialogFileNameBuff);
5317 #endif
5318 }
5319
5320 // ****************************************************************************
5321 // Edit Ctl.
5322
5323 void VprintfEditCtlWnd(HWND hwnd, char *fmt, va_list argList)
5324 {
5325          char buffer[BUFSIZ], out[BUFSIZ];
5326          char *in;
5327          int i;
5328
5329          if(!IsWindow(hwnd))
5330                   return;
5331
5332          vsnprintf(buffer, sizeof(buffer), fmt, argList);
5333          in = buffer;
5334          i = 0;
5335          for(;;){
5336                   if(*in == '\0' || i>sizeof(out)-3){
5337                                 out[i] = '\0';
5338                                 break;
5339                   }
5340                   if(*in=='\n'){
5341                                 out[i] = 13;
5342                                 out[i+1] = 10;
5343                                 in++;
5344                                 i += 2;
5345                                 continue;
5346                   }
5347                   out[i] = *in;
5348                   in++;
5349                   i++;
5350          }
5351
5352      {
5353          int len = GetWindowTextLength(hwnd);
5354          Edit_SetSel(hwnd, len, len);
5355          Edit_ReplaceSel(hwnd, out);
5356      }
5357 }
5358
5359 void PrintfEditCtlWnd(HWND hwnd, char *fmt, ...)
5360 {
5361     va_list ap;
5362     va_start(ap, fmt);
5363     VprintfEditCtlWnd(hwnd,fmt,ap);
5364     va_end(ap);
5365 }
5366
5367 #if 1
5368 void PutsEditCtlWnd(HWND hwnd, char *str)
5369 {
5370         char *in = str;
5371         int i;
5372         char out[BUFSIZ];
5373         i = 0;
5374         for(;;){
5375                 if(*in == '\0' || i>sizeof(out)-3){
5376                         out[i] = '\0';
5377                         break;
5378     }
5379         if(*in=='\n'){
5380         out[i] = 13;
5381         out[i+1] = 10;
5382                         in++;
5383       i += 2;
5384       continue;
5385     }
5386     out[i] = *in;
5387                 in++;
5388     i++;
5389   }
5390         if(IsWindow(hwnd)){
5391         int len = GetWindowTextLength(hwnd);
5392                 Edit_SetSel(hwnd, len, len);
5393                 Edit_ReplaceSel(hwnd,out);
5394         }
5395 }
5396 #else
5397 void PutsEditCtlWnd(HWND hwnd, char *str)
5398 {
5399         if(!IsWindow(hwnd))
5400                 return;
5401         PrintfEditCtlWnd(hwnd,"%s",str);
5402 }
5403 #endif
5404
5405 void ClearEditCtlWnd(HWND hwnd)
5406 {
5407         char pszVoid[]="";
5408         if(!IsWindow(hwnd))
5409                 return;
5410         if(IsWindow(hwnd)){
5411 //              Edit_SetSel(hwnd,0,-1);
5412                 Edit_SetSel(hwnd,-1,-1);
5413         }
5414         Edit_SetText(hwnd,pszVoid);
5415 }
5416
5417
5418 // ****************************************************************************
5419 // Misc funciton.
5420
5421 int w32g_msg_box(char *message, char *title, int type)
5422 {
5423     return MessageBox(hMainWnd, message, title, type);
5424 }
5425
5426
5427 //#define RC_QUEUE_SIZE 8
5428 #define RC_QUEUE_SIZE 48
5429 static struct
5430 {
5431     int rc;
5432     ptr_size_t value;
5433 } rc_queue[RC_QUEUE_SIZE];
5434 static volatile int rc_queue_len, rc_queue_beg, rc_queue_end;
5435
5436 static HANDLE w32g_lock_sem = NULL;
5437 static HANDLE w32g_empty_sem = NULL;
5438
5439 void w32g_lock(void)
5440 {
5441         if(w32g_lock_sem)
5442             WaitForSingleObject(w32g_lock_sem, INFINITE);
5443 }
5444
5445 void w32g_unlock(void)
5446 {
5447         if(w32g_lock_sem)
5448             ReleaseSemaphore(w32g_lock_sem, 1, NULL);
5449 }
5450
5451 void w32g_send_rc(int rc, ptr_size_t value)
5452 {
5453     w32g_lock();
5454
5455     if(rc_queue_len == RC_QUEUE_SIZE)
5456     {
5457         /* Over flow.  Remove the oldest message */
5458         rc_queue_len--;
5459         rc_queue_beg = (rc_queue_beg + 1) % RC_QUEUE_SIZE;
5460     }
5461
5462     rc_queue_len++;
5463     rc_queue[rc_queue_end].rc = rc;
5464     rc_queue[rc_queue_end].value = value;
5465     rc_queue_end = (rc_queue_end + 1) % RC_QUEUE_SIZE;
5466         if(w32g_empty_sem)
5467             ReleaseSemaphore(w32g_empty_sem, 1, NULL);
5468     w32g_unlock();
5469 }
5470
5471 int w32g_get_rc(ptr_size_t *value, int wait_if_empty)
5472 {
5473     int rc;
5474
5475     while(rc_queue_len == 0)
5476     {
5477         if(!wait_if_empty)
5478             return RC_NONE;
5479         if(w32g_empty_sem)
5480                 WaitForSingleObject(w32g_empty_sem, INFINITE);
5481         VOLATILE_TOUCH(rc_queue_len);
5482     } 
5483
5484     w32g_lock();
5485     rc = rc_queue[rc_queue_beg].rc;
5486     *value = rc_queue[rc_queue_beg].value;
5487     rc_queue_len--;
5488     rc_queue_beg = (rc_queue_beg + 1) % RC_QUEUE_SIZE;
5489     w32g_unlock();
5490
5491     return rc;
5492 }
5493
5494 int w32g_open(void)
5495 {
5496     SaveSettingTiMidity(st_current);
5497     memcpy(st_temp, st_current, sizeof(SETTING_TIMIDITY));
5498
5499     w32g_lock_sem = CreateSemaphore(NULL, 1, 1, "TiMidity Mutex Lock");
5500     w32g_empty_sem = CreateSemaphore(NULL, 0, 8, "TiMidity Empty Lock");
5501
5502     hPlayerThread = GetCurrentThread();
5503     w32g_wait_for_init = 1;
5504     hMainThread = crt_beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE)MainThread, NULL, 0, &dwMainThreadID);
5505
5506     while(w32g_wait_for_init)
5507     {
5508                 Sleep(0);
5509                 VOLATILE_TOUCH(w32g_wait_for_init);
5510     }
5511     return 0;
5512 }
5513
5514 static void terminate_main_thread(void)
5515 {
5516         DWORD status;
5517
5518         switch(WaitForSingleObject(hMainThread, 0))
5519         {
5520           case WAIT_OBJECT_0:
5521                 break;
5522           case WAIT_TIMEOUT:
5523                 OnQuit();
5524                 status = WaitForSingleObject(hMainThread, 5000);
5525                 if(status == WAIT_TIMEOUT)
5526                         TerminateThread(hMainThread, 0);
5527                 break;
5528           default:
5529                 TerminateThread(hMainThread, 0);
5530                 break;
5531         }
5532 }
5533
5534 void w32g_close(void)
5535 {       
5536         terminate_main_thread();
5537         if(w32g_lock_sem){
5538             CloseHandle(w32g_lock_sem);
5539                 w32g_lock_sem = NULL;
5540         }
5541         if(w32g_empty_sem){
5542             CloseHandle(w32g_empty_sem);
5543                 w32g_empty_sem = NULL;
5544         }
5545 }
5546
5547 void w32g_restart(void)
5548 {
5549         w32g_restart_gui_flag = 1;
5550
5551         terminate_main_thread();
5552         if(w32g_lock_sem){
5553             CloseHandle(w32g_lock_sem);
5554                 w32g_lock_sem = NULL;
5555         }
5556         if(w32g_empty_sem){
5557             CloseHandle(w32g_empty_sem);
5558                 w32g_empty_sem = NULL;
5559         }
5560
5561         /* Reset variable */
5562     hDebugEditWnd = 0;
5563
5564         /* Now ready to start */
5565         w32g_open();
5566         w32g_restart_gui_flag = 0;
5567 }
5568
5569 void w32g_ctle_play_start(int sec)
5570 {
5571     char *title;
5572
5573     if(sec >= 0)
5574     {
5575         SetScrollRange(hMainWndScrollbarProgressWnd, SB_CTL, 0, sec, TRUE);
5576         MainWndScrollbarProgressUpdate(0);
5577     }
5578     else
5579         MainWndScrollbarProgressUpdate(-1);
5580
5581     Panel->cur_time_h = MPanel.CurTime_h = 0;
5582     Panel->cur_time_m = MPanel.CurTime_m = 0;
5583     Panel->cur_time_s = MPanel.CurTime_s = 0;
5584     Panel->cur_time_ss = MPanel.CurTime_ss = 0;
5585
5586     MPanel.TotalTime_h = sec / 60 / 60;
5587     RANGE(MPanel.TotalTime_h, 0, 99);
5588     Panel->total_time_h = MPanel.TotalTime_h;
5589
5590     sec %= 60 * 60;
5591     Panel->total_time_m = MPanel.TotalTime_m = sec / 60;
5592     Panel->total_time_s = MPanel.TotalTime_s = sec % 60;
5593     Panel->total_time_ss = MPanel.TotalTime_ss = 0;
5594
5595     MPanel.UpdateFlag |= MP_UPDATE_TIME;
5596
5597     /* Now, ready to get the title of MIDI */
5598     if((title = get_midi_title(MPanel.File)) != NULL)
5599     {
5600         strncpy(MPanel.Title, title, MP_TITLE_MAX);
5601         MPanel.UpdateFlag |= MP_UPDATE_TITLE;
5602     }
5603     MPanelUpdate();
5604
5605
5606 }
5607
5608 void MainWndScrollbarProgressUpdate(int sec)
5609 {
5610     static int lastsec = -1, enabled = 0;
5611
5612     if(sec == lastsec)
5613         return;
5614
5615     if(sec == -1)
5616     {
5617         EnableWindow(hMainWndScrollbarProgressWnd, FALSE);
5618         enabled = 0;
5619         progress_jump = -1;
5620     }
5621     else
5622     {
5623         if(!enabled)
5624         {
5625             EnableWindow(hMainWndScrollbarProgressWnd, TRUE);
5626             enabled = 1;
5627         }
5628         if(progress_jump == -1)
5629             SetScrollPos(hMainWndScrollbarProgressWnd, SB_CTL, sec, TRUE);
5630     }
5631     lastsec = sec;
5632 }
5633
5634 void w32g_show_console(void)
5635 {
5636         ShowWindow(hConsoleWnd, SW_SHOW);
5637         SendDlgItemMessage(hMainWnd, IDC_TOOLBARWINDOW_SUBWND,
5638                                            TB_CHECKBUTTON, IDM_CONSOLE, (LPARAM)MAKELONG(TRUE, 0));
5639 }
5640
5641 //
5642 // GDI \83A\83N\83Z\83X\82ð\92P\88ê\83X\83\8c\83b\83h\82É\8cÀ\92è\82·\82é\82½\82ß\82Ì\83\8d\83b\83N\8b@\8d\
5643
5644 static HANDLE volatile hMutexGDI = NULL;
5645 // static int volatile lock_num = 0;
5646 int gdi_lock_ex ( DWORD timeout )
5647 {
5648 // lock_num++;
5649 // ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
5650 //                "gdi_lock<%d %d>", GetCurrentThreadId(),lock_num );
5651         if(hMutexGDI==NULL){
5652                 hMutexGDI = CreateMutex(NULL,FALSE,NULL);
5653                 if(hMutexGDI==NULL)
5654                         return -1;
5655         }
5656         if(WaitForSingleObject(hMutexGDI,timeout)==WAIT_FAILED){
5657                 return -1;
5658         }
5659         return 0;
5660 }
5661 int gdi_lock(void)
5662 {
5663         return gdi_lock_ex ( INFINITE );
5664 }
5665
5666 extern int gdi_unlock(void)
5667 {
5668 //lock_num--;
5669 //ctl->cmsg(CMSG_INFO, VERB_VERBOSE,
5670 //                "gdi_unlock<%d %d>", GetCurrentThreadId(),lock_num );
5671         if(hMutexGDI!=NULL){
5672                 ReleaseMutex(hMutexGDI);
5673         }
5674         return 0;
5675 }