diff options
Diffstat (limited to 'c/main.cpp')
-rw-r--r-- | c/main.cpp | 232 |
1 files changed, 122 insertions, 110 deletions
@@ -3,11 +3,13 @@ #include <uxtheme.h> #include <SWI-Prolog.h> +#include <cstdio> + #include "resource.h" #include "defs.h" -DataListView g_dlv; -EpisodeListView g_elv; +DataListView *g_lpDlv = nullptr; +EpisodeListView *g_lpElv = nullptr; atom_t g_aThread; char g_szLimitScreenwriter[64] = {0}; @@ -17,36 +19,53 @@ HMENU g_hPopupMenu; HWND g_hFocus; HWND g_hWnd; HWND g_hWndStatus; -int g_bThemes; +int g_bThemes = 0; int g_bViewTVOriginal = 1; int g_bViewWatched = 1; int g_bThread = 0; int g_iDPI = -1; static int g_cxVScroll; +static LRESULT CALLBACK CBTProc(int, WPARAM, LPARAM); static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); static HWND CreateStatusBar(HWND, HINSTANCE); static int Attach(void); -static void SetupFonts(void); static void UpdateTheme(void); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) { - HWND hWnd; + HMODULE hModule; LPTSTR tszErr; /* Set constant values. */ - HMODULE hModule = LoadLibrary(TEXT("uxtheme.dll")); - g_bThemes = hModule && GetProcAddress(hModule, "SetWindowTheme"); - if (hModule) FreeLibrary(hModule); + hModule = LoadLibrary(TEXT("uxtheme.dll")); + if (hModule && GetProcAddress(hModule, "SetWindowTheme")) { + g_bThemes = 1; + FreeLibrary(hModule); + } g_cxVScroll = GetSystemMetrics(SM_CXVSCROLL); + /* Setup fonts. */ + hModule = LoadLibrary(TEXT("User32.dll")); + if (hModule && GetProcAddress(hModule, "SystemParametersInfoW")) { + NONCLIENTMETRICS m; + m.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, + sizeof(NONCLIENTMETRICS), &m, 0); + g_hfNormal = CreateFontIndirect(&m.lfMessageFont); + FreeLibrary(hModule); + } else + g_hfNormal = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)); + + LOGFONT lf; + GetObject(g_hfNormal, sizeof(LOGFONT), &lf); + lf.lfWeight = FW_BOLD; + g_fBold = CreateFontIndirect(&lf); + /* Initialize Prolog. */ - char *argv[2]; - argv[0] = (char *)"EpisodeBrowser"; - argv[1] = NULL; + char *argv[] = { (char *)"EpisodeBrowser", NULL }; tszErr = TEXT("Could not initialize Prolog."); if (!PL_initialise(1, argv)) goto f; tszErr = TEXT("Could not attach databases."); @@ -76,7 +95,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, tszErr = TEXT("Could not register window class."); if (!RegisterClassEx(&wc)) goto f; - /* Create window. */ + /* Create window. Note that a CBT hook is used to initialize + * important global variables before any messages are sent to + * the new window. */ + HHOOK hHook; + HWND hWnd; + hHook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId()); hWnd = CreateWindowEx( 0, TEXT("Episode Browser"), @@ -85,6 +109,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInstance, NULL ); + UnhookWindowsHookEx(hHook); tszErr = TEXT("Could not create main window."); if (!hWnd) goto f; g_hWndStatus = CreateStatusBar(hWnd, hInstance); @@ -92,8 +117,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, /* Populate episode list view. */ Pl("track_episodes", "update_tracked_episodes", ""); - g_elv.Update(); - g_elv.RestoreFocus(); + g_lpElv->Update(); + g_lpElv->RestoreFocus(); MSG msg; while (GetMessage(&msg, NULL, 0, 0) > 0) { @@ -109,48 +134,55 @@ f: MessageBox(NULL, tszErr, TEXT("Error"), MB_ICONERROR); return 1; } +static LRESULT CALLBACK +CBTProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode != HCBT_CREATEWND) return 0; + if (g_hWnd) return 0; + + /* This code is run once at the creation of the top-level + * window -- before WndProc! This is important, as it + * initializes global variables that are used by WndProc. */ + + g_hWnd = (HWND)wParam; + g_lpDlv = new DataListView; + g_lpElv = new EpisodeListView; + + /* Get DPI. */ + UINT (*GetDpiForWindow)(HWND); + HMODULE hModule = LoadLibrary(TEXT("User32.dll")); + if (hModule && (GetDpiForWindow = (UINT (*)(HWND))GetProcAddress(hModule, "GetDpiForWindow"))) { + g_iDPI = GetDpiForWindow(g_hWnd); + FreeLibrary(hModule); + } else + g_iDPI = 96; + + /* Get saved view settings. */ + char *sz; + Pl("cfg","get_view_watched","i",&g_bViewWatched); + Pl("cfg","get_view_tv_original","i",&g_bViewTVOriginal); + if (Pl("cfg","get_limit_screenwriter","s",&sz)) + strcpy_s(g_szLimitScreenwriter, sizeof(g_szLimitScreenwriter), sz); + return 0; +} + LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: { - g_hWnd = hWnd; - - /* Get DPI. */ - UINT (*GetDpiForWindow)(HWND); - HMODULE hModule = LoadLibrary(TEXT("User32.dll")); - if (hModule && (GetDpiForWindow = (UINT (*)(HWND))GetProcAddress(hModule, "GetDpiForWindow"))) { - g_iDPI = GetDpiForWindow(g_hWnd); - FreeLibrary(hModule); - } else - g_iDPI = 96; - - /* Set window size. */ + UpdateTheme(); SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(400), SWP_NOMOVE); + SetFocus(g_lpElv->HWnd()); - /* Get and apply saved view settings. */ - if (Pl("cfg","get_view_watched","i",&g_bViewWatched)) - CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED, - g_bViewWatched? MF_CHECKED: MF_UNCHECKED); - - if (Pl("cfg","get_view_tv_original","i",&g_bViewTVOriginal)) - CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL, - g_bViewTVOriginal? MF_CHECKED: MF_UNCHECKED); - - char *sz; - if (!Pl("cfg","get_limit_screenwriter","s",&sz)) - goto s; - strcpy_s(g_szLimitScreenwriter, - sizeof(g_szLimitScreenwriter), sz); + /* Set menu item checkmarks according to saved settings. */ + CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED, + g_bViewWatched? MF_CHECKED: MF_UNCHECKED); + CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL, + g_bViewTVOriginal? MF_CHECKED: MF_UNCHECKED); CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS, g_szLimitScreenwriter[0]? MF_UNCHECKED: MF_CHECKED); - - s: SetupFonts(); - g_dlv.Create(); - g_elv.Create(); - UpdateTheme(); - SetFocus(g_elv.HWnd()); break; } case WM_CLOSE: @@ -158,7 +190,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case WM_DESTROY: { - g_elv.SaveFocus(); + g_lpElv->SaveFocus(); PostQuitMessage(0); break; } @@ -170,7 +202,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; lpMMI->ptMinTrackSize.x = Dpi(220); - lpMMI->ptMinTrackSize.y = g_dlv.Height(0)+Dpi(180); + lpMMI->ptMinTrackSize.y = Dpi(220); break; } case WM_THEMECHANGED: @@ -197,13 +229,13 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WA_CLICKACTIVE: SetFocus(g_hFocus); Pl("track_episodes","update_tracked_episodes",""); - g_elv.Redraw(); + g_lpElv->Redraw(); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_EPISODELISTVIEW: - return g_elv.HandleNotify(lParam); + return g_lpElv->HandleNotify(lParam); } break; case WM_TIMER: @@ -224,7 +256,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else { i = 0; KillTimer(hWnd, IDT_TIMER); - g_elv.Update(); + g_lpElv->Update(); } break; } @@ -236,7 +268,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) PostMessage(hWnd, WM_CLOSE, 0, 0); break; case IDM_FILE_REFRESH: - g_elv.Update(); + g_lpElv->Update(); break; case IDM_FILE_FETCH_DATA: if (g_bThread) break; @@ -264,8 +296,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) g_bViewWatched? MF_UNCHECKED: MF_CHECKED); g_bViewWatched = !g_bViewWatched; Pl("cfg","set_view_watched","I",g_bViewWatched); - g_elv.Update(); - g_elv.EnsureFocusVisible(); + g_lpElv->Update(); + g_lpElv->EnsureFocusVisible(); break; } case IDM_VIEW_TV_ORIGINAL: @@ -274,8 +306,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) g_bViewTVOriginal? MF_UNCHECKED: MF_CHECKED); g_bViewTVOriginal = !g_bViewTVOriginal; Pl("cfg","set_view_tv_original","I",g_bViewTVOriginal); - g_elv.Update(); - g_elv.EnsureFocusVisible(); + g_lpElv->Update(); + g_lpElv->EnsureFocusVisible(); break; } case IDM_VIEW_OTHERS: /* Show/hide other screenwriters. */ @@ -286,13 +318,13 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) MF_CHECKED); g_szLimitScreenwriter[0] = 0; } else { - iEpFocus = ListView_GetNextItem(g_elv.HWnd(), -1, LVNI_FOCUSED); + iEpFocus = ListView_GetNextItem(g_lpElv->HWnd(), -1, LVNI_FOCUSED); if (iEpFocus == -1) break; LVITEM lvi; lvi.iItem = iEpFocus; lvi.mask = LVIF_PARAM; - if (!ListView_GetItem(g_elv.HWnd(), &lvi)) break; + if (!ListView_GetItem(g_lpElv->HWnd(), &lvi)) break; char *sz; if (!Pl("episode_data","episode_datum","ISs",lvi.lParam,"Screenwriter",&sz)) @@ -303,8 +335,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) MF_UNCHECKED); } Pl("cfg","set_limit_screenwriter","S",g_szLimitScreenwriter); - g_elv.Update(); - g_elv.EnsureFocusVisible(); + g_lpElv->Update(); + g_lpElv->EnsureFocusVisible(); break; } case IDM_WATCH_LOCALLY: @@ -334,8 +366,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) lvi.mask = LVIF_PARAM; lvi.iItem = -1; while ((lvi.iItem = ListView_GetNextItem( - g_elv.HWnd(), lvi.iItem, LVNI_SELECTED)) != -1) { - if (!ListView_GetItem(g_elv.HWnd(), &lvi)) goto b; + g_lpElv->HWnd(), lvi.iItem, LVNI_SELECTED)) != -1) { + if (!ListView_GetItem(g_lpElv->HWnd(), &lvi)) goto b; switch (LOWORD(wParam)) { case IDM_WATCH_LOCALLY: @@ -346,18 +378,18 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case IDM_TOGGLE: Pl("track_episodes","toggle_episode","I",lvi.lParam); - g_elv.Redraw(); + g_lpElv->Redraw(); break; case IDM_FORGET: Pl("track_episodes","forget_episode","I",lvi.lParam); Pl("track_episodes","update_tracked_episodes",""); - g_elv.Redraw(); + g_lpElv->Redraw(); break; case IDM_LOOKUP: Pl("episode_data","retract_episode","I",lvi.lParam); - g_elv.UpdateItem(&lvi); - g_elv.Redraw(); - g_dlv.ShowEpisode(lvi.lParam); + g_lpElv->UpdateItem(&lvi); + g_lpElv->Redraw(); + g_lpDlv->ShowEpisode(lvi.lParam); break; case IDM_WIKI: Pl("episode_data","open_episode_wiki","I",lvi.lParam); @@ -395,7 +427,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDM_RATE0: iRating = 0; r: Pl("episode_data","rate_episode","II",lvi.lParam,iRating); - g_elv.UpdateItem(&lvi); + g_lpElv->UpdateItem(&lvi); break; } } @@ -411,9 +443,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDM_RATE2: case IDM_RATE1: case IDM_RATE0: - g_elv.Redraw(); - g_elv.DoSort(); - g_elv.ShowFocus(); + g_lpElv->Redraw(); + g_lpElv->DoSort(); + g_lpElv->ShowFocus(); } b: break; } @@ -475,27 +507,6 @@ Attach() return 1; } -void -SetupFonts() -{ - HMODULE hModule = LoadLibrary(TEXT("User32.dll")); - if (hModule && GetProcAddress(hModule, "SystemParametersInfoW")) { - NONCLIENTMETRICS m; - m.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, - sizeof(NONCLIENTMETRICS), &m, 0); - g_hfNormal = CreateFontIndirect(&m.lfMessageFont); - FreeLibrary(hModule); - } else - g_hfNormal = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)); - - - LOGFONT lf; - GetObject(g_hfNormal, sizeof(LOGFONT), &lf); - lf.lfWeight = FW_BOLD; - g_fBold = CreateFontIndirect(&lf); -} - /***/ void @@ -509,24 +520,24 @@ UpdateLayout() yStatus = rcStatus.bottom-rcStatus.top; /* Resize data list view. */ - SendMessage(g_dlv.HWnd(), WM_SETREDRAW, FALSE, 0); - SendMessage(g_elv.HWnd(), WM_SETREDRAW, FALSE, 0); - cyDlv = rc.bottom-yStatus-g_dlv.Height(DLVSIKEY); - MoveWindow(g_dlv.HWnd(), 0, cyDlv, rc.right, rc.bottom-yStatus-cyDlv, TRUE); - ListView_SetColumnWidth(g_dlv.HWnd(), DLVSIKEY, LVSCW_AUTOSIZE); - cxColumn = ListView_GetColumnWidth(g_dlv.HWnd(), 0)+4; - ListView_SetColumnWidth(g_dlv.HWnd(), DLVSIKEY, cxColumn); - ListView_SetColumnWidth(g_dlv.HWnd(), DLVSIVALUE, rc.right-cxColumn-g_cxVScroll-4); + SendMessage(g_lpDlv->HWnd(), WM_SETREDRAW, FALSE, 0); + SendMessage(g_lpElv->HWnd(), WM_SETREDRAW, FALSE, 0); + cyDlv = rc.bottom-yStatus-g_lpDlv->Height(DLVSIKEY); + MoveWindow(g_lpDlv->HWnd(), 0, cyDlv, rc.right, rc.bottom-yStatus-cyDlv, TRUE); + ListView_SetColumnWidth(g_lpDlv->HWnd(), DLVSIKEY, LVSCW_AUTOSIZE); + cxColumn = ListView_GetColumnWidth(g_lpDlv->HWnd(), 0)+4; + ListView_SetColumnWidth(g_lpDlv->HWnd(), DLVSIKEY, cxColumn); + ListView_SetColumnWidth(g_lpDlv->HWnd(), DLVSIVALUE, rc.right-cxColumn-g_cxVScroll-4); /* Resize episode list view. */ - MoveWindow(g_elv.HWnd(), 0, 0, rc.right, cyDlv+1, TRUE); - ListView_SetColumnWidth(g_elv.HWnd(), ELVSIEPISODE, LVSCW_AUTOSIZE); - cxColumn = ListView_GetColumnWidth(g_elv.HWnd(), ELVSIEPISODE)+4; - ListView_SetColumnWidth(g_elv.HWnd(), ELVSIEPISODE, cxColumn); - cxColumn += ListView_GetColumnWidth(g_elv.HWnd(), ELVSIRATING); - ListView_SetColumnWidth(g_elv.HWnd(), ELVSITITLE, rc.right-cxColumn-g_cxVScroll-4); - SendMessage(g_elv.HWnd(), WM_SETREDRAW, TRUE, 0); - SendMessage(g_dlv.HWnd(), WM_SETREDRAW, TRUE, 0); + MoveWindow(g_lpElv->HWnd(), 0, 0, rc.right, cyDlv+1, TRUE); + ListView_SetColumnWidth(g_lpElv->HWnd(), ELVSIEPISODE, LVSCW_AUTOSIZE); + cxColumn = ListView_GetColumnWidth(g_lpElv->HWnd(), ELVSIEPISODE)+4; + ListView_SetColumnWidth(g_lpElv->HWnd(), ELVSIEPISODE, cxColumn); + cxColumn += ListView_GetColumnWidth(g_lpElv->HWnd(), ELVSIRATING); + ListView_SetColumnWidth(g_lpElv->HWnd(), ELVSITITLE, rc.right-cxColumn-g_cxVScroll-4); + SendMessage(g_lpElv->HWnd(), WM_SETREDRAW, TRUE, 0); + SendMessage(g_lpDlv->HWnd(), WM_SETREDRAW, TRUE, 0); /* Resize status bar parts. */ int aParts[] = {rc.right-Dpi(55), rc.right}; @@ -537,7 +548,8 @@ UpdateLayout() void UpdateTheme() { + if (!g_bThemes) return; BOOL bThemeActive = IsThemeActive(); - g_dlv.UpdateTheme(bThemeActive); - g_elv.UpdateTheme(bThemeActive); + g_lpDlv->UpdateTheme(bThemeActive); + g_lpElv->UpdateTheme(bThemeActive); } |