aboutsummaryrefslogtreecommitdiff
path: root/c/main.c
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-07-10 23:23:09 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-07-10 23:25:09 +0200
commit295d423cc47f9ee8a72134dc544892a03b279311 (patch)
tree3e89b0bbcf42b3053225eb0dff88b887dd16df48 /c/main.c
parent85a4ad2c184ed915915a2fb630415a80ed9a286f (diff)
downloadEpisodeBrowser-295d423cc47f9ee8a72134dc544892a03b279311.tar.gz
Convert to C++.
I already hit upon some object-oriented programming patterns in *listview.c, so I felt that it would be natural to use this as an opportunity to learn C++.
Diffstat (limited to 'c/main.c')
-rw-r--r--c/main.c581
1 files changed, 0 insertions, 581 deletions
diff --git a/c/main.c b/c/main.c
deleted file mode 100644
index ef3877a..0000000
--- a/c/main.c
+++ /dev/null
@@ -1,581 +0,0 @@
-#include <windows.h>
-#include <commctrl.h>
-#include <uxtheme.h>
-#include <SWI-Prolog.h>
-
-#include "resource.h"
-#include "defs.h"
-
-atom_t AThread;
-char SzLimitScreenwriter[64] = {0};
-HFONT HfNormal;
-HFONT HfBold;
-HMENU HPopupMenu;
-HWND HFocus;
-HWND HWnd;
-HWND HWndStatus;
-int BViewTVOriginal = 1;
-int BViewWatched = 1;
-int BThread = 0;
-int IDPI = -1;
-static int BThemes;
-static int CxVScroll;
-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)
-{
- char *argv[2];
- HMODULE hModule;
- HWND hWnd;
- LPTSTR tszErr;
- MSG msg;
- INITCOMMONCONTROLSEX icc;
- WNDCLASSEX wc;
-
- /* Set constant values. */
- hModule = LoadLibrary(TEXT("uxtheme.dll"));
- BThemes = hModule && GetProcAddress(hModule,"SetWindowTheme");
- if (hModule) FreeLibrary(hModule);
- CxVScroll = GetSystemMetrics(SM_CXVSCROLL);
-
- /* Initialize Prolog. */
- argv[0] = "EpisodeBrowser";
- argv[1] = NULL;
- tszErr = TEXT("Could not initialize Prolog.");
- if (!PL_initialise(1, argv)) goto f;
- tszErr = TEXT("Could not attach databases.");
- if (!Attach()) goto f;
-
- /* Initialize common controls, load menu and register window class. */
- icc.dwSize = sizeof(icc);
- icc.dwICC = ICC_WIN95_CLASSES;
- tszErr = TEXT("Could not initialize common controls.");
- if (!InitCommonControlsEx(&icc)) goto f;
-
- HPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU));
- HPopupMenu = GetSubMenu(HPopupMenu, 0);
-
- memset(&wc, 0, sizeof(WNDCLASSEX));
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.lpfnWndProc = WndProc;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
- wc.lpszClassName = TEXT("Episode Browser");
- wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- tszErr = TEXT("Could not register window class.");
- if (!RegisterClassEx(&wc)) goto f;
-
- /* Create window. */
- hWnd = CreateWindowEx(
- 0,
- TEXT("Episode Browser"),
- TEXT("Episode Browser"),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
- NULL, NULL, hInstance, NULL
- );
- tszErr = TEXT("Could not create main window.");
- if (!hWnd) goto f;
- HWndStatus = CreateStatusBar(hWnd, hInstance);
- ShowWindow(hWnd, nCmdShow);
-
- /* Populate episode list view. */
- Pl("track_episodes", "update_tracked_episodes", "");
- ElvUpdate();
- ElvSelectFocus();
-
- while (GetMessage(&msg, NULL, 0, 0) > 0) {
- if (IsDialogMessage(hWnd, &msg)) continue;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- PL_halt(0);
- return 0;
-f: MessageBox(NULL, tszErr, TEXT("Error"), MB_ICONERROR);
- PL_halt(1);
- return 1;
-}
-
-LRESULT CALLBACK
-WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_CREATE:
- {
- HMODULE hModule;
- FARPROC GetDpiForWindow;
- extern HWND HWnd, HElv;
- HWnd = hWnd;
- IDPI = 96;
- hModule = LoadLibrary(TEXT("User32.dll"));
- if (hModule && (GetDpiForWindow = GetProcAddress(hModule, "GetDpiForWindow"))) {
- IDPI = GetDpiForWindow(HWnd);
- FreeLibrary(hModule);
- }
- SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(400), SWP_NOMOVE);
- if (Pl("cfg","get_view_watched","i",&BViewWatched))
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED,
- BViewWatched? MF_CHECKED: MF_UNCHECKED);
- if (Pl("cfg","get_view_tv_original","i",&BViewTVOriginal))
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL,
- BViewTVOriginal? MF_CHECKED: MF_UNCHECKED);
- {
- char *sz;
- if (!Pl("cfg","get_limit_screenwriter","s",&sz))
- goto s;
- strcpy_s(SzLimitScreenwriter,
- sizeof(SzLimitScreenwriter), sz);
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS,
- SzLimitScreenwriter[0]? MF_UNCHECKED: MF_CHECKED);
- }
- s: SetupFonts();
- DlvCreate();
- ElvCreate();
- UpdateTheme();
- SetFocus(HElv);
- break;
- }
- case WM_CLOSE:
- DestroyWindow(hWnd);
- break;
- case WM_DESTROY:
- {
- LVITEM lvi;
- extern HWND HElv;
- lvi.mask = LVIF_PARAM;
- if ((lvi.iItem=ListView_GetNextItem(HElv,-1,LVNI_FOCUSED)) != -1
- && ListView_GetItem(HElv, &lvi))
- Pl("cfg","set_focus","I",lvi.lParam);
- PostQuitMessage(0);
- break;
- }
- case WM_SIZE:
- SendMessage(HWndStatus, WM_SIZE, wParam, lParam);
- UpdateLayout();
- break;
- case WM_GETMINMAXINFO:
- {
- LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
- extern HWND HDlv;
- lpMMI->ptMinTrackSize.y = LvHeight(HDlv, 0)+80;
- break;
- }
- case WM_THEMECHANGED:
- UpdateTheme();
- break;
- case 0x02E0: /* WM_DPICHANGED */
- {
- LPRECT lpr;
- lpr = (LPRECT)lParam;
- IDPI = HIWORD(wParam);
- SetWindowPos(hWnd, NULL,
- lpr->left, lpr->top,
- lpr->right-lpr->left,
- lpr->bottom-lpr->top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- UpdateLayout();
- break;
- }
- case WM_ACTIVATE:
- switch (wParam) {
- case WA_INACTIVE:
- HFocus = GetFocus();
- break;
- case WA_ACTIVE:
- case WA_CLICKACTIVE:
- SetFocus(HFocus);
- Pl("track_episodes","update_tracked_episodes","");
- ElvRedraw();
- }
- break;
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->idFrom) {
- case IDC_EPISODELISTVIEW:
- return ElvHandleNotify(lParam);
- }
- break;
- case WM_TIMER:
- switch (wParam) {
- case IDT_TIMER:
- {
- static int i = 0;
- if (Pl("episode_data","thread_running","A",AThread)) {
- i = (i+1)%4;
- SendMessage(HWndStatus, SB_SETTEXT, MAKEWPARAM(1,0),
- (LPARAM)(i==0? TEXT("."):
- i==1? TEXT(".."):
- i==2? TEXT("..."):
- TEXT("")));
- } else {
- i = 0;
- KillTimer(hWnd, IDT_TIMER);
- ElvUpdate();
- }
- break;
- }
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDM_FILE_EXIT:
- PostMessage(hWnd, WM_CLOSE, 0, 0);
- break;
- case IDM_FILE_REFRESH:
- ElvUpdate();
- break;
- case IDM_FILE_FETCH_DATA:
- if (BThread) break;
- Pl("episode_data","thread_create","Sa","update_episode_data",&AThread);
- goto t;
- case IDM_FILE_FETCH_SCREENWRITERS:
- if (BThread) break;
- Pl("episode_data","thread_create","Sa","update_screenwriters",&AThread);
- t: KillTimer(hWnd, IDT_TIMER);
- SetTimer(hWnd, IDT_TIMER, 500, NULL);
- SendMessage(HWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)TEXT("."));
- BThread = 1;
- break;
- case IDM_FILE_ABOUT:
- DialogBox(
- GetModuleHandle(NULL),
- MAKEINTRESOURCE(IDD_ABOUT),
- hWnd,
- AboutDlgProc
- );
- break;
- case IDM_VIEW_WATCHED:
- {
- int iEpFocus;
- extern HWND HElv;
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED,
- BViewWatched? MF_UNCHECKED: MF_CHECKED);
- BViewWatched = !BViewWatched;
- ElvUpdate();
- Pl("cfg","set_view_watched","I",BViewWatched);
- iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED);
- if (iEpFocus == -1) break;
- ListView_EnsureVisible(HElv, iEpFocus, TRUE);
- break;
- }
- case IDM_VIEW_TV_ORIGINAL:
- {
- int iEpFocus;
- extern HWND HElv;
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL,
- BViewTVOriginal? MF_UNCHECKED: MF_CHECKED);
- BViewTVOriginal = !BViewTVOriginal;
- ElvUpdate();
- Pl("cfg","set_view_tv_original","I",BViewTVOriginal);
- iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED);
- if (iEpFocus == -1) break;
- ListView_EnsureVisible(HElv, iEpFocus, TRUE);
- break;
- }
- case IDM_VIEW_OTHERS: /* Show/hide other screenwriters. */
- {
- int iEpFocus;
- extern HWND HElv;
- if (SzLimitScreenwriter[0]) {
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS,
- MF_CHECKED);
- SzLimitScreenwriter[0] = 0;
- } else {
- char *sz;
- LVITEM lvi;
- iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED);
- if (iEpFocus == -1) break;
- lvi.iItem = iEpFocus;
- lvi.mask = LVIF_PARAM;
- if (!ListView_GetItem(HElv, &lvi)) break;
- if (!Pl("episode_data","episode_datum","ISs",
- lvi.lParam,"Screenwriter",&sz))
- break;
- strcpy_s(SzLimitScreenwriter,
- sizeof(SzLimitScreenwriter), sz);
- CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS,
- MF_UNCHECKED);
- }
- ElvUpdate();
- Pl("cfg","set_limit_screenwriter","S",
- SzLimitScreenwriter);
- iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED);
- if (iEpFocus == -1) break;
- ListView_EnsureVisible(HElv, iEpFocus, TRUE);
- break;
- }
- case IDM_WATCH_LOCALLY:
- case IDM_WATCH_ONLINE:
- case IDM_TOGGLE:
- case IDM_FORGET:
- case IDM_LOOKUP:
- case IDM_WIKI:
- case IDM_RATE10:
- case IDM_RATE9:
- case IDM_RATE8:
- case IDM_RATE7:
- case IDM_RATE6:
- case IDM_RATE5:
- case IDM_RATE4:
- case IDM_RATE3:
- case IDM_RATE2:
- case IDM_RATE1:
- case IDM_RATE0:
- {
- int iRating;
- LVITEM lvi;
- extern HWND HElv;
-
- /* Look through selected items, applying the
- * selected command to each one. */
-
- lvi.mask = LVIF_PARAM;
- lvi.iItem = -1;
- while ((lvi.iItem = ListView_GetNextItem(
- HElv, lvi.iItem, LVNI_SELECTED)) != -1) {
- if (!ListView_GetItem(HElv, &lvi)) goto b;
-
- switch (LOWORD(wParam)) {
- case IDM_WATCH_LOCALLY:
- Pl("local_episode","open_episode_locally","I",lvi.lParam);
- break;
- case IDM_WATCH_ONLINE:
- Pl("local_episode","open_episode_online","I",lvi.lParam);
- break;
- case IDM_TOGGLE:
- Pl("track_episodes","toggle_episode","I",lvi.lParam);
- ElvRedraw();
- break;
- case IDM_FORGET:
- Pl("track_episodes","forget_episode","I",lvi.lParam);
- Pl("track_episodes","update_tracked_episodes","");
- ElvRedraw();
- break;
- case IDM_LOOKUP:
- Pl("episode_data","retract_episode","I",lvi.lParam);
- ElvUpdateItem(&lvi);
- ElvRedraw();
- DlvShowEpisode(lvi.lParam);
- break;
- case IDM_WIKI:
- Pl("episode_data","open_episode_wiki","I",lvi.lParam);
- break;
- case IDM_RATE10:
- iRating = 10;
- goto r;
- case IDM_RATE9:
- iRating = 9;
- goto r;
- case IDM_RATE8:
- iRating = 8;
- goto r;
- case IDM_RATE7:
- iRating = 7;
- goto r;
- case IDM_RATE6:
- iRating = 6;
- goto r;
- case IDM_RATE5:
- iRating = 5;
- goto r;
- case IDM_RATE4:
- iRating = 4;
- goto r;
- case IDM_RATE3:
- iRating = 3;
- goto r;
- case IDM_RATE2:
- iRating = 2;
- goto r;
- case IDM_RATE1:
- iRating = 1;
- goto r;
- case IDM_RATE0:
- iRating = 0;
- r: Pl("episode_data","rate_episode","II",lvi.lParam,iRating);
- ElvUpdateItem(&lvi);
- break;
- }
- }
- switch (LOWORD(wParam)) {
- case IDM_RATE10:
- case IDM_RATE9:
- case IDM_RATE8:
- case IDM_RATE7:
- case IDM_RATE6:
- case IDM_RATE5:
- case IDM_RATE4:
- case IDM_RATE3:
- case IDM_RATE2:
- case IDM_RATE1:
- case IDM_RATE0:
- ElvRedraw();
- ElvDoSort();
- ElvShowFocus();
- }
- b: break;
- }
- }
- break;
- default:
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
-
- return 0;
-}
-
-INT_PTR CALLBACK
-AboutDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_CLOSE:
- EndDialog(hWnd, IDOK);
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- EndDialog(hWnd, IDOK);
- break;
- }
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
-HWND
-CreateStatusBar(HWND hWndParent, HINSTANCE hInstance)
-{
- HWND hWnd;
- hWnd = CreateWindowEx(
- 0,
- STATUSCLASSNAME,
- (LPCTSTR) NULL,
- WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP,
- 0, 0, 0, 0,
- hWndParent,
- (HMENU)ID_STATUS,
- hInstance,
- NULL
- );
- return hWnd;
-}
-
-/***/
-
-/* Attach persistent databases. */
-int
-Attach()
-{
- if (!Pl("track_episodes","attach","")) return 0;
- if (!Pl("episode_data","attach","")) return 0;
- return 1;
-}
-
-void
-SetupFonts()
-{
- HMODULE hModule;
- LOGFONT lf;
-
- hModule = LoadLibrary(TEXT("User32.dll"));
- if (hModule && GetProcAddress(hModule, "SystemParametersInfoW")) {
- NONCLIENTMETRICS m;
- m.cbSize = sizeof(NONCLIENTMETRICS);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
- sizeof(NONCLIENTMETRICS), &m, 0);
- HfNormal = CreateFontIndirect(&m.lfMessageFont);
- FreeLibrary(hModule);
- } else
- HfNormal = GetStockObject(DEFAULT_GUI_FONT);
-
- GetObject(HfNormal, sizeof(LOGFONT), &lf);
- lf.lfWeight = FW_BOLD;
- HfBold = CreateFontIndirect(&lf);
-}
-
-/***/
-
-void
-UpdateLayout()
-{
- int cxColumn, cyDlv, yStatus;
- RECT rc, rcStatus;
- extern HWND HDlv, HElv;
-
- GetClientRect(HWnd, &rc);
- GetClientRect(HWndStatus, &rcStatus);
- yStatus = rcStatus.bottom-rcStatus.top;
-
- /* Resize data list view. */
- SendMessage(HDlv, WM_SETREDRAW, FALSE, 0);
- SendMessage(HElv, WM_SETREDRAW, FALSE, 0);
- cyDlv = rc.bottom-yStatus-LvHeight(HDlv, DLVSIKEY);
- MoveWindow(HDlv, 0, cyDlv, rc.right, rc.bottom-yStatus-cyDlv, TRUE);
- ListView_SetColumnWidth(HDlv, DLVSIKEY, LVSCW_AUTOSIZE);
- cxColumn = ListView_GetColumnWidth(HDlv, 0)+4;
- ListView_SetColumnWidth(HDlv, DLVSIKEY, cxColumn);
- ListView_SetColumnWidth(HDlv, DLVSIVALUE, rc.right-cxColumn-CxVScroll-4);
-
- /* Resize episode list view. */
- MoveWindow(HElv, 0, 0, rc.right, cyDlv+1, TRUE);
- ListView_SetColumnWidth(HElv, ELVSIEPISODE, LVSCW_AUTOSIZE);
- cxColumn = ListView_GetColumnWidth(HElv, ELVSIEPISODE)+4;
- ListView_SetColumnWidth(HElv, ELVSIEPISODE, cxColumn);
- cxColumn += ListView_GetColumnWidth(HElv, ELVSIRATING);
- ListView_SetColumnWidth(HElv, ELVSITITLE, rc.right-cxColumn-CxVScroll-4);
- SendMessage(HElv, WM_SETREDRAW, TRUE, 0);
- SendMessage(HDlv, WM_SETREDRAW, TRUE, 0);
-
- /* Resize status bar parts. */
- {
- int aParts[] = {rc.right-Dpi(55), rc.right};
- SendMessage(HWndStatus, SB_SETPARTS,
- (WPARAM)sizeof(aParts), (LPARAM)aParts);
- }
-}
-
-/* Try to style application according to current Windows theme. */
-void
-UpdateTheme()
-{
- DWORD dwStyle;
- LPTSTR tszTheme;
- WORD wAction;
- extern HWND HElv, HDlv;
-
- if (!BThemes) return;
- if (IsThemeActive()) {
- dwStyle = LVS_EX_DOUBLEBUFFER;
- tszTheme = TEXT("Explorer");
- wAction = UIS_SET;
- } else {
- dwStyle = 0;
- tszTheme = NULL;
- wAction = UIS_CLEAR;
- }
-
- /* Use modern "Explorer" theme. */
- SetWindowTheme(HElv, tszTheme, NULL);
- SetWindowTheme(HDlv, tszTheme, NULL);
-
- /* The modern theme requires double buffering. */
- ListView_SetExtendedListViewStyleEx(HElv, LVS_EX_DOUBLEBUFFER, dwStyle);
- ListView_SetExtendedListViewStyleEx(HDlv, LVS_EX_DOUBLEBUFFER, dwStyle);
-
- /* Hide focus rectangles. */
- SendMessage(HElv, WM_UPDATEUISTATE, MAKEWPARAM(wAction, UISF_HIDEFOCUS), 0);
- SendMessage(HDlv, WM_UPDATEUISTATE, MAKEWPARAM(wAction, UISF_HIDEFOCUS), 0);
-}