diff options
-rw-r--r-- | .dir-locals.el | 4 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | README | 12 | ||||
-rw-r--r-- | c/common.cpp (renamed from c/common.c) | 2 | ||||
-rw-r--r-- | c/datalistview.cpp (renamed from c/datalistview.c) | 28 | ||||
-rw-r--r-- | c/defs.h | 71 | ||||
-rw-r--r-- | c/episodelistview.cpp (renamed from c/episodelistview.c) | 295 | ||||
-rw-r--r-- | c/listview.c | 78 | ||||
-rw-r--r-- | c/listview.cpp | 76 | ||||
-rw-r--r-- | c/main.cpp (renamed from c/main.c) | 268 | ||||
-rw-r--r-- | c/pl.cpp (renamed from c/pl.c) | 14 |
12 files changed, 453 insertions, 404 deletions
diff --git a/.dir-locals.el b/.dir-locals.el index 62e25f6..6c6dcc0 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,2 +1,4 @@ ((c-mode . ((flycheck-gcc-include-path . ("C:/Program Files/swipl/include")) - (flycheck-gcc-definitions . ("UNICODE" "_UNICODE"))))) + (flycheck-gcc-definitions . ("UNICODE" "_UNICODE")))) + (c++-mode . ((flycheck-gcc-include-path . ("C:/Program Files/swipl/include")) + (flycheck-gcc-definitions . ("UNICODE" "_UNICODE"))))) @@ -2,3 +2,4 @@ /misc/ TAGS *~ +*.db @@ -1,6 +1,6 @@ B = build/default/ -C = c/main.c +C = c/main.cpp PL = pl/cfg.pl pl/episode_data.pl pl/local_episodes.pl pl/track_episodes.pl OBJ = $(B)common.obj $(B)datalistview.obj $(B)episodelistview.obj $(B)listview.obj $(B)pl.obj $(B)resource.obj @@ -18,11 +18,11 @@ $(B)EpisodeBrowser.exe: $(C) $(OBJ) $(PL) c/defs.h Makefile $(B)resource.obj: c/resource.h c/resource.rc c/application.manifest windres -i c/resource.rc -o $(B)resource.obj -$(B)%.obj: c/%.c c/defs.h +$(B)%.obj: c/%.cpp c/*.h $(CC) -c $(CFLAGS) -o $@ $< -TAGS: c/*.c c/*.h pl/*.pl - etags c/*.c c/*.h -lprolog pl/*.pl +TAGS: c/*.cpp c/*.h pl/*.pl + etags c/*.cpp c/*.h -lprolog pl/*.pl clean: rm -fr $(B)EpisodeBrowser.exe $(B)*.obj @@ -28,16 +28,16 @@ modified. Frontend ~~~~~~~~ -The graphical interface is implemented in C using the Win32 API (see +The graphical interface is implemented in C++ using the Win32 API (see the c folder). The source code is spread across a small number of files. For an overview of the functions provided by each file, see defs.h. In summary: -main.c Entry point and initialization. Contains the main event handler. -listview.c Creates and handles the shared aspects of the two list views. -episodelistview.c Defines the interface to the episode list view. -datalistview.c Defines the interface to the data list view. -common.c Some useful functions that don't fit elsewhere. +main.cpp Entry point and initialization. Contains the main event handler. +listview.cpp Creates and handles the shared aspects of the two list views. +episodelistview.cpp Defines the interface to the episode list view. +datalistview.cpp Defines the interface to the data list view. +common.cpp Some useful functions that don't fit elsewhere. The frontend interacts with the Prolog backend via the SWI-Prolog API. Note, however, that most interaction is done through ten or so macros, diff --git a/c/common.c b/c/common.cpp index a056993..63adb53 100644 --- a/c/common.c +++ b/c/common.cpp @@ -15,7 +15,7 @@ TszFromSz(const char *sz, int iCp) cbMultiByte = strlen(sz)+1; cchWideChar = MultiByteToWideChar(iCp, 0, sz, cbMultiByte, NULL, 0); - tsz = malloc(cchWideChar*sizeof(WCHAR)); + tsz = (TCHAR *)malloc(cchWideChar*sizeof(WCHAR)); if (!tsz) return NULL; if (!MultiByteToWideChar(iCp, 0, sz, cbMultiByte, tsz, cchWideChar)) return NULL; diff --git a/c/datalistview.c b/c/datalistview.cpp index fbb46d0..3269dab 100644 --- a/c/datalistview.c +++ b/c/datalistview.cpp @@ -6,42 +6,38 @@ #include "resource.h" #include "defs.h" -HWND HDlv; +extern EpisodeListView g_elv; -HWND -DlvCreate() +void +DataListView::Create() { LVCOLUMN lvc; - HDlv = LvCreate((HMENU)IDC_DATALISTVIEW, LVS_NOCOLUMNHEADER); + ListView::Create((HMENU)IDC_DATALISTVIEW, LVS_NOCOLUMNHEADER); lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = DLVSIKEY; lvc.pszText = TEXT("Key"); lvc.cx = Dpi(42); - ListView_InsertColumn(HDlv, DLVSIKEY, &lvc); + ListView_InsertColumn(m_hWnd, DLVSIKEY, &lvc); lvc.iSubItem = DLVSIVALUE; lvc.pszText = TEXT("Value"); lvc.cx = 500; - ListView_InsertColumn(HDlv, DLVSIVALUE, &lvc); - - return HDlv; + ListView_InsertColumn(m_hWnd, DLVSIVALUE, &lvc); } -/* Show episode data. */ void -DlvShowEpisode(int iEpisode) +DataListView::ShowEpisode(int iEpisode) { int i, iItem; LVFINDINFO lvfi; LVITEM lviKey, lviValue; term_t t; qid_t q; - extern HWND HElv; - ListView_DeleteAllItems(HDlv); + ListView_DeleteAllItems(m_hWnd); lviKey.mask = LVIF_TEXT; lviValue.mask = LVIF_TEXT; @@ -67,12 +63,12 @@ DlvShowEpisode(int iEpisode) lviKey.iItem = i; lviKey.iSubItem = 0; lviKey.pszText = tszKey; - ListView_InsertItem(HDlv, &lviKey); + ListView_InsertItem(m_hWnd, &lviKey); lviValue.iItem = i; lviValue.iSubItem = 1; lviValue.pszText = tszValue; - ListView_SetItem(HDlv, &lviValue); + ListView_SetItem(m_hWnd, &lviValue); free(tszValue); c: free(tszKey); @@ -83,7 +79,7 @@ DlvShowEpisode(int iEpisode) lvfi.flags = LVFI_PARAM; lvfi.lParam = iEpisode; - iItem = ListView_FindItem(HElv, -1, &lvfi); + iItem = ListView_FindItem(g_elv.HWnd(), -1, &lvfi); if (iItem != -1) - ListView_EnsureVisible(HElv, iItem, TRUE); + ListView_EnsureVisible(g_elv.HWnd(), iItem, TRUE); } @@ -5,36 +5,51 @@ #include <commctrl.h> #include <SWI-Prolog.h> -/* common.c */ +/* common.cpp */ TCHAR *TszFromSz(const char *, int); -/* main.c */ +/* main.cpp */ void UpdateLayout(); -/* listview.c */ -HWND LvCreate(HMENU, DWORD); -int LvHeight(HWND, int); - -/* episodelistview.c */ -HWND ElvCreate(); -void ElvDoSort(void); -LRESULT ElvHandleNotify(LPARAM); -void ElvRedraw(void); -void ElvSetTop(int); -void ElvSelectFocus(void); -void ElvSelectUnwatched(int); -void ElvShowFocus(void); -void ElvUpdate(void); -void ElvUpdateItem(LPLVITEM); - -/* datalistview.c */ -HWND DlvCreate(); -void DlvShowEpisode(int); - -/* pl.c */ -int Pl(char *, char *, char *, ...); -int Plp(term_t, char *, ...); -int Plg(term_t, char *, ...); +/* listview.cpp */ +class ListView { +protected: + WNDPROC m_prevProc; + HWND m_hWnd; +public: + void Create(HMENU, DWORD); + int Height(int); + HWND HWnd(void); + virtual LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +}; + +/* episodelistview.cpp */ +class EpisodeListView: public ListView { +public: + void Create(void); + void DoSort(void); + LRESULT HandleNotify(LPARAM); + void Redraw(void); + void SetTop(int); + void SelectFocus(void); + void SelectUnwatched(int); + void ShowFocus(void); + void Update(void); + void UpdateItem(LPLVITEM); + LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +}; + +/* datalistview.cpp */ +class DataListView: public ListView { +public: + void Create(void); + void ShowEpisode(int); +}; + +/* pl.cpp */ +int Pl(const char *, const char *, const char *, ...); +int Plp(term_t, const char *, ...); +int Plg(term_t, const char *, ...); /* defs.h */ #define DLVSIKEY 0 @@ -56,8 +71,8 @@ Cmp(int a, int b) inline int Dpi(int i) { - extern int IDPI; - return MulDiv(i, IDPI, 96); + extern int g_iDPI; + return MulDiv(i, g_iDPI, 96); } #endif diff --git a/c/episodelistview.c b/c/episodelistview.cpp index a1973f8..8fb3ec7 100644 --- a/c/episodelistview.c +++ b/c/episodelistview.cpp @@ -6,48 +6,50 @@ #include "resource.h" #include "defs.h" -HWND HElv; +extern DataListView g_dlv; + +HWND HSortLv; + int ISort; LVITEM LviElvFocus; /* Focused episode. */ static int CALLBACK ElvSort(LPARAM, LPARAM, LPARAM); -HWND -ElvCreate() +void +EpisodeListView::Create() { LVCOLUMN lvc; - HElv = LvCreate((HMENU)IDC_EPISODELISTVIEW, 0); + ListView::Create((HMENU)IDC_EPISODELISTVIEW, 0); lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = ELVSIEPISODE; lvc.pszText = TEXT("#"); lvc.cx = Dpi(42); - ListView_InsertColumn(HElv, ELVSIEPISODE, &lvc); + ListView_InsertColumn(m_hWnd, ELVSIEPISODE, &lvc); lvc.iSubItem = ELVSITITLE; lvc.pszText = TEXT("Title"); lvc.cx = 500; - ListView_InsertColumn(HElv, ELVSITITLE, &lvc); + ListView_InsertColumn(m_hWnd, ELVSITITLE, &lvc); lvc.iSubItem = ELVSIRATING; lvc.pszText = TEXT("/"); lvc.cx = Dpi(30); - ListView_InsertColumn(HElv, ELVSIRATING, &lvc); + ListView_InsertColumn(m_hWnd, ELVSIRATING, &lvc); if (!Pl("cfg","get_sort","i",&ISort)) ISort = 1; - - return HElv; } void -ElvDoSort() +EpisodeListView::DoSort() { - ListView_SortItemsEx(HElv, ElvSort, ISort); + HSortLv = m_hWnd; + ListView_SortItemsEx(m_hWnd, ElvSort, ISort); } LRESULT -ElvHandleNotify(LPARAM lParam) +EpisodeListView::HandleNotify(LPARAM lParam) { LPNMLISTVIEW lpNmLv; lpNmLv = (LPNMLISTVIEW)lParam; @@ -58,8 +60,8 @@ ElvHandleNotify(LPARAM lParam) (lpNmLv->uNewState & LVIS_FOCUSED)) { LviElvFocus.iItem = lpNmLv->iItem; LviElvFocus.lParam = lpNmLv->lParam; - ElvUpdateItem(&LviElvFocus); - DlvShowEpisode(lpNmLv->lParam); + UpdateItem(&LviElvFocus); + g_dlv.ShowEpisode(lpNmLv->lParam); } break; case LVN_COLUMNCLICK: /* Sort by column. */ @@ -68,8 +70,8 @@ ElvHandleNotify(LPARAM lParam) iColumn = lpNmLv->iSubItem+1; ISort = abs(ISort) == iColumn? -ISort: iColumn; Pl("cfg","set_sort","I",ISort); - s: ElvDoSort(); - ElvShowFocus(); + DoSort(); + ShowFocus(); break; } case LVN_KEYDOWN: /* Navigate episodes by keyboard. */ @@ -78,10 +80,10 @@ ElvHandleNotify(LPARAM lParam) lpNmLvKd = (LPNMLVKEYDOWN)lParam; switch (lpNmLvKd->wVKey) { case VK_LEFT: - ElvSelectUnwatched(-1); + SelectUnwatched(-1); break; case VK_RIGHT: - ElvSelectUnwatched(1); + SelectUnwatched(1); break; } break; @@ -96,9 +98,9 @@ ElvHandleNotify(LPARAM lParam) break; case CDDS_ITEMPREPAINT: { - extern HFONT HfBold; + extern HFONT g_fBold; if (!Pl("track_episodes","watched","I",lpLvCd->nmcd.lItemlParam)) { - SelectObject(lpLvCd->nmcd.hdc, HfBold); + SelectObject(lpLvCd->nmcd.hdc, g_fBold); return CDRF_NEWFONT; } break; @@ -117,12 +119,11 @@ ElvHandleNotify(LPARAM lParam) case NM_RETURN: /* Open all selected episodes. */ { LVITEM lvi; - extern HWND HElv; 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; + m_hWnd, lvi.iItem, LVNI_SELECTED)) != -1) { + if (!ListView_GetItem(m_hWnd, &lvi)) goto b; if (!Pl("local_episodes","open_episode_locally","I", lvi.lParam)) Pl("local_episodes","open_episode_online","I", @@ -133,12 +134,12 @@ ElvHandleNotify(LPARAM lParam) case NM_RCLICK: { DWORD dwPos; - extern HWND HWnd; - extern HMENU HPopupMenu; + extern HWND g_hWnd; + extern HMENU g_hPopupMenu; dwPos = GetMessagePos(); - TrackPopupMenu(HPopupMenu, TPM_RIGHTBUTTON, + TrackPopupMenu(g_hPopupMenu, TPM_RIGHTBUTTON, LOWORD(dwPos), HIWORD(dwPos), 0, - HWnd, NULL); + g_hWnd, NULL); break; } } @@ -147,24 +148,24 @@ ElvHandleNotify(LPARAM lParam) } void -ElvRedraw() +EpisodeListView::Redraw() { - RedrawWindow(HElv, NULL, NULL, + RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } void -ElvSetTop(int iItem) +EpisodeListView::SetTop(int iItem) { int iLast; - iLast = ListView_GetItemCount(HElv)-1; - ListView_EnsureVisible(HElv, iLast, TRUE); - ListView_EnsureVisible(HElv, iItem, TRUE); + iLast = ListView_GetItemCount(m_hWnd)-1; + ListView_EnsureVisible(m_hWnd, iLast, TRUE); + ListView_EnsureVisible(m_hWnd, iItem, TRUE); } /* Select previously focused episode. */ void -ElvSelectFocus() +EpisodeListView::SelectFocus() { int i, iEpisode, iItem; LVFINDINFO lvfi; @@ -175,31 +176,31 @@ ElvSelectFocus() lvfi.flags = LVFI_PARAM; lvfi.lParam = iEpisode; i = 0; - while ((iItem = ListView_FindItem(HElv, -1, &lvfi)) == -1 && i++ < 100) + while ((iItem = ListView_FindItem(m_hWnd, -1, &lvfi)) == -1 && i++ < 100) lvfi.lParam = ++iEpisode; if (iItem != -1) goto s; iEpisode -= 100; lvfi.lParam = iEpisode; i = 0; - while ((iItem = ListView_FindItem(HElv, -1, &lvfi)) == -1 && i++ < 100) + while ((iItem = ListView_FindItem(m_hWnd, -1, &lvfi)) == -1 && i++ < 100) lvfi.lParam = --iEpisode; if (iItem != -1) goto s; return; -s: ListView_SetItemState(HElv, -1, LVIF_STATE, LVIS_SELECTED); - ElvSetTop(iItem > 5? iItem-5: 0); - ListView_SetItemState(HElv, iItem, +s: ListView_SetItemState(m_hWnd, -1, LVIF_STATE, LVIS_SELECTED); + SetTop(iItem > 5? iItem-5: 0); + ListView_SetItemState(m_hWnd, iItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); LviElvFocus.iItem = iItem; LviElvFocus.lParam = iEpisode; - ElvUpdateItem(&LviElvFocus); - DlvShowEpisode(iEpisode); + UpdateItem(&LviElvFocus); + g_dlv.ShowEpisode(iEpisode); } /* Select next/previous unwatched episode. */ void -ElvSelectUnwatched(int iDir) +EpisodeListView::SelectUnwatched(int iDir) { int i, iEpNew, iItemNew; LVFINDINFO lvfi; @@ -207,8 +208,8 @@ ElvSelectUnwatched(int iDir) /* Get focused episode. */ lviFocus.mask = LVIF_PARAM; - if ((lviFocus.iItem = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED)) != -1 - && ListView_GetItem(HElv, &lviFocus)) + if ((lviFocus.iItem = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED)) != -1 + && ListView_GetItem(m_hWnd, &lviFocus)) ; else return; @@ -223,130 +224,83 @@ ElvSelectUnwatched(int iDir) return; lvfi.lParam = iEpNew; - if ((iItemNew = ListView_FindItem(HElv, -1, &lvfi)) != -1) { - ListView_SetItemState(HElv,-1,LVIF_STATE,LVIS_SELECTED); - ListView_SetSelectionMark(HElv, iItemNew); - ListView_SetItemState(HElv, iItemNew, + if ((iItemNew = ListView_FindItem(m_hWnd, -1, &lvfi)) != -1) { + ListView_SetItemState(m_hWnd,-1,LVIF_STATE,LVIS_SELECTED); + ListView_SetSelectionMark(m_hWnd, iItemNew); + ListView_SetItemState(m_hWnd, iItemNew, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); - ElvRedraw(); - ListView_EnsureVisible(HElv, iItemNew, TRUE); + Redraw(); + ListView_EnsureVisible(m_hWnd, iItemNew, TRUE); return; } } while (i++ < 1000); } void -ElvShowFocus() +EpisodeListView::ShowFocus() { int iEpFocus; - iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED); + iEpFocus = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED); if (iEpFocus == -1) return; - ListView_EnsureVisible(HElv, iEpFocus, TRUE); -} - -/* Sort list view items, iSort being the 1-based index of the column - * to sort by. If iSort is negative, the order is descending. */ -int CALLBACK -ElvSort(LPARAM iItem1, LPARAM iItem2, LPARAM iSort) -{ - int iOrder; - LVITEM lvi1, lvi2; - lvi1.mask = lvi2.mask = LVIF_PARAM; - lvi1.iItem = iItem1; lvi2.iItem = iItem2; - if (!ListView_GetItem(HElv, &lvi1)) return 0; - if (!ListView_GetItem(HElv, &lvi2)) return 0; - iOrder = Cmp(iSort, 0); - switch (abs(iSort)-1) { - case ELVSIEPISODE: - return iOrder*Cmp(lvi1.lParam, lvi2.lParam); - break; - case ELVSIRATING: - { - int iRating1, iRating2; - iRating1 = iSort > 0? 99: -1; - iRating2 = iSort > 0? 99: -1; - Pl("episode_data","episode_rating","Ii",lvi1.lParam,&iRating1); - Pl("episode_data","episode_rating","Ii",lvi2.lParam,&iRating2); - if (iRating1 == iRating2) - return Cmp(lvi1.lParam, lvi2.lParam); - return iOrder*Cmp(iRating1, iRating2); - break; - } - case ELVSITITLE: - { - char *sz1, *sz2; - int cch, cch1, cch2; - if (!Pl("episode_data","episode_title","Is",lvi1.lParam,&sz1)) - return 0; - if (!Pl("episode_data","episode_title","Is",lvi2.lParam,&sz2)) - return 0; - cch1 = strlen(sz1); - cch2 = strlen(sz2); - cch = cch1 > cch2? cch2: cch1; - return iOrder*_strnicmp(sz1, sz2, cch); - break; - } - default: - return 0; - } + ListView_EnsureVisible(m_hWnd, iEpFocus, TRUE); } /* Update episode list. */ void -ElvUpdate() +EpisodeListView::Update() { int cEp, i, iEp, iEpFocus, iItem, iItemMark, iItemTopNew; LVITEM lvi, lviEpisode, lviTop; LVFINDINFO lvfi; - extern HWND HWndStatus; - static TCHAR tszDisp[16], tszEpisode[16], tszTotal[16]; + extern HWND g_hWndStatus; + static TCHAR tszDisp[16], tszEpisode[16]; static int aEpSel[2048]; lviEpisode.mask = LVIF_TEXT|LVIF_PARAM; /* Save scrolling position. */ - lviTop.iItem = ListView_GetTopIndex(HElv); + lviTop.iItem = ListView_GetTopIndex(m_hWnd); lviTop.mask = LVIF_PARAM; - ListView_GetItem(HElv, &lviTop); + ListView_GetItem(m_hWnd, &lviTop); /* Save selected episodes. */ i = 0; lvi.mask = LVIF_PARAM; lvi.iItem = -1; while ((lvi.iItem = ListView_GetNextItem( - HElv, lvi.iItem, LVNI_SELECTED)) != -1 + m_hWnd, lvi.iItem, LVNI_SELECTED)) != -1 && i < 2048) - if (ListView_GetItem(HElv, &lvi)) + if (ListView_GetItem(m_hWnd, &lvi)) aEpSel[i++] = lvi.lParam; aEpSel[i] = 0; - iItemMark = ListView_GetSelectionMark(HElv); + iItemMark = ListView_GetSelectionMark(m_hWnd); /* Save focus. */ iEpFocus = 0; - if ((lvi.iItem = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED)) != -1 - && ListView_GetItem(HElv, &lvi)) + if ((lvi.iItem = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED)) != -1 + && ListView_GetItem(m_hWnd, &lvi)) iEpFocus = lvi.lParam; - SendMessage(HElv, WM_SETREDRAW, FALSE, 0); - ListView_DeleteAllItems(HElv); + SendMessage(m_hWnd, WM_SETREDRAW, FALSE, 0); + ListView_DeleteAllItems(m_hWnd); if (!Pl("episode_data","ensure_episode_data","")) return; if (!Pl("episode_data","episode_count","i",&cEp)) return; for (iEp = 1, iItem = 0; iEp <= cEp; iEp++) { - extern char SzLimitScreenwriter[]; - extern int BViewTVOriginal, BViewWatched; + extern char g_szLimitScreenwriter[]; + extern int g_bViewTVOriginal, g_bViewWatched; - if (SzLimitScreenwriter[0]) + if (g_szLimitScreenwriter[0]) if (!Pl("episode_data","episode_datum","ISS", - iEp,"Screenwriter",SzLimitScreenwriter)) + iEp,"Screenwriter",g_szLimitScreenwriter)) continue; - if (!BViewWatched) + if (!g_bViewWatched) if (Pl("track_episodes","watched","I",iEp)) continue; - if (!BViewTVOriginal) + if (!g_bViewTVOriginal) if (Pl("episode_data","tv_original","I",iEp)) continue; /* Format episode number string. */ @@ -357,11 +311,11 @@ ElvUpdate() lviEpisode.iSubItem = ELVSIEPISODE; lviEpisode.pszText = tszEpisode; lviEpisode.lParam = iEp; - ListView_InsertItem(HElv, &lviEpisode); - ElvUpdateItem(&lviEpisode); + ListView_InsertItem(m_hWnd, &lviEpisode); + UpdateItem(&lviEpisode); } - ElvDoSort(); + DoSort(); lvfi.flags = LVFI_PARAM; @@ -369,12 +323,12 @@ ElvUpdate() for (i = 0; aEpSel[i]; i++) { int iItemSel; lvfi.lParam = aEpSel[i]; - if ((iItemSel = ListView_FindItem(HElv, -1, &lvfi)) != -1) - ListView_SetItemState(HElv, iItemSel, + if ((iItemSel = ListView_FindItem(m_hWnd, -1, &lvfi)) != -1) + ListView_SetItemState(m_hWnd, iItemSel, LVIS_SELECTED, LVIS_SELECTED); } if (iItemMark != -1) - ListView_SetSelectionMark(HElv, iItemMark); + ListView_SetSelectionMark(m_hWnd, iItemMark); /* Reset focus. */ if (iEpFocus) { @@ -382,10 +336,10 @@ ElvUpdate() i = 0; do lvfi.lParam = iEpFocus+i; - while ((iItemFocus = ListView_FindItem(HElv, -1, &lvfi)) == -1 + while ((iItemFocus = ListView_FindItem(m_hWnd, -1, &lvfi)) == -1 && i++ < 100); if (iItemFocus != -1) - ListView_SetItemState(HElv, iItemFocus, + ListView_SetItemState(m_hWnd, iItemFocus, LVIS_FOCUSED, LVIS_FOCUSED); } @@ -394,19 +348,19 @@ ElvUpdate() i = 0; do lvfi.lParam = lviTop.lParam+i; - while ((iItemTopNew = ListView_FindItem(HElv, -1, &lvfi)) == -1 + while ((iItemTopNew = ListView_FindItem(m_hWnd, -1, &lvfi)) == -1 && i++ < 100); if (iItemTopNew != -1) - ElvSetTop(iItemTopNew); + SetTop(iItemTopNew); _stprintf_s(tszDisp, sizeof(tszDisp), TEXT("%d"), iItem); - SendMessage(HWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)tszDisp); - SendMessage(HElv, WM_SETREDRAW, TRUE, 0); + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)tszDisp); + SendMessage(m_hWnd, WM_SETREDRAW, TRUE, 0); } /* Update episode name and rating. */ void -ElvUpdateItem(LPLVITEM lpLvi) +EpisodeListView::UpdateItem(LPLVITEM lpLvi) { char *szName; int iRating; @@ -417,19 +371,90 @@ ElvUpdateItem(LPLVITEM lpLvi) if (!Pl("episode_data","episode_title","Is",lpLvi->lParam,&szName)) { if (!Pl("episode_data","update_episode_data","")) goto r; if (!Pl("episode_data","episode_title","Is",lpLvi->lParam,&szName)) - goto r; + goto r; } tszName = TszFromSz(szName, CP_UTF8); if (tszName) - ListView_SetItemText(HElv, lpLvi->iItem, ELVSITITLE, tszName); + ListView_SetItemText(m_hWnd, lpLvi->iItem, ELVSITITLE, tszName); r: if (!Pl("episode_data","episode_rating","Ii",lpLvi->lParam,&iRating)) { - ListView_SetItemText(HElv, lpLvi->iItem, ELVSIRATING, TEXT("")); + ListView_SetItemText(m_hWnd, lpLvi->iItem, ELVSIRATING, TEXT("")); goto f; } _stprintf_s(tszRating, sizeof(tszRating), TEXT("%d"), iRating); - ListView_SetItemText(HElv, lpLvi->iItem, ELVSIRATING, tszRating); + ListView_SetItemText(m_hWnd, lpLvi->iItem, ELVSIRATING, tszRating); f: if (tszName) free(tszName); } + +/* Sort list view items, iSort being the 1-based index of the column + * to sort by. If iSort is negative, the order is descending. */ +int CALLBACK +ElvSort(LPARAM iItem1, LPARAM iItem2, LPARAM iSort) +{ + int iOrder; + LVITEM lvi1, lvi2; + lvi1.mask = lvi2.mask = LVIF_PARAM; + lvi1.iItem = iItem1; lvi2.iItem = iItem2; + if (!ListView_GetItem(HSortLv, &lvi1)) return 0; + if (!ListView_GetItem(HSortLv, &lvi2)) return 0; + iOrder = Cmp(iSort, 0); + switch (abs(iSort)-1) { + case ELVSIEPISODE: + return iOrder*Cmp(lvi1.lParam, lvi2.lParam); + break; + case ELVSIRATING: + { + int iRating1, iRating2; + iRating1 = iSort > 0? 99: -1; + iRating2 = iSort > 0? 99: -1; + Pl("episode_data","episode_rating","Ii",lvi1.lParam,&iRating1); + Pl("episode_data","episode_rating","Ii",lvi2.lParam,&iRating2); + if (iRating1 == iRating2) + return Cmp(lvi1.lParam, lvi2.lParam); + return iOrder*Cmp(iRating1, iRating2); + break; + } + case ELVSITITLE: + { + char *sz1, *sz2; + int cch, cch1, cch2; + if (!Pl("episode_data","episode_title","Is",lvi1.lParam,&sz1)) + return 0; + if (!Pl("episode_data","episode_title","Is",lvi2.lParam,&sz2)) + return 0; + cch1 = strlen(sz1); + cch2 = strlen(sz2); + cch = cch1 > cch2? cch2: cch1; + return iOrder*_strnicmp(sz1, sz2, cch); + break; + } + default: + return 0; + } +} + +LRESULT CALLBACK +EpisodeListView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_GETDLGCODE: + { + LRESULT lResult; + + /* For the episode list view, the Enter key should not + * be handled by the dialog manager, but instead be sent + * along to the main window procedure, so that it may be + * handled by the NM_RETURN case in ElvHandleNotify. */ + + lResult = CallWindowProc(m_prevProc, hWnd, uMsg, wParam, lParam); + if (lParam && ((MSG *)lParam)->message == WM_KEYDOWN + && ((MSG *)lParam)->wParam == VK_RETURN) + return DLGC_WANTMESSAGE; + return lResult; + } + } + + return ListView::WndProc(hWnd, uMsg, wParam, lParam); +} diff --git a/c/listview.c b/c/listview.c deleted file mode 100644 index 91838da..0000000 --- a/c/listview.c +++ /dev/null @@ -1,78 +0,0 @@ -#include <windows.h> -#include <commctrl.h> -#include <uxtheme.h> - -#include "resource.h" -#include "defs.h" - -extern HFONT HfNormal; -extern HWND HWnd; -WNDPROC LvPrevProc; -static LRESULT CALLBACK LvProc(HWND, UINT, WPARAM, LPARAM); - -HWND -LvCreate(HMENU hMenu, DWORD dwStyle) -{ - HWND hLv; - - hLv = CreateWindowEx( - WS_EX_CLIENTEDGE, - WC_LISTVIEW, - TEXT(""), - dwStyle|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP - |LVS_REPORT|LVS_SHOWSELALWAYS, - 0, 0, 0, 0, - HWnd, hMenu, GetModuleHandle(NULL), NULL - ); - - LvPrevProc = (WNDPROC)SetWindowLongPtr(hLv, - GWLP_WNDPROC, (LONG_PTR)LvProc); - - ListView_SetExtendedListViewStyle(hLv, LVS_EX_FULLROWSELECT); - - SendMessage(hLv, WM_SETFONT, (WPARAM)HfNormal, MAKELPARAM(FALSE, 0)); - - return hLv; -} - -LRESULT CALLBACK -LvProc(HWND hLv, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case HDN_ENDTRACK: - UpdateLayout(); - return TRUE; - } - break; - case WM_GETDLGCODE: - { - LRESULT lResult; - extern HWND HElv; - - /* For the episode list view, the Enter key should not - * be handled by the dialog manager, but instead be sent - * along to the main window procedure, so that it may be - * handled by the NM_RETURN case in ElvHandleNotify. */ - - if (hLv != HElv) break; - lResult = CallWindowProc(LvPrevProc, hLv, uMsg, wParam, lParam); - if (lParam && ((MSG *)lParam)->message == WM_KEYDOWN - && ((MSG *)lParam)->wParam == VK_RETURN) - return DLGC_WANTMESSAGE; - return lResult; - } - } - - return CallWindowProc(LvPrevProc, hLv, uMsg, wParam, lParam); -} - -/* Naively calculate height of list view. */ -int -LvHeight(HWND hLv, int bHeader) -{ - int iCount; - iCount = ListView_GetItemCount(hLv); - return iCount? Dpi(bHeader? 27: 4)+iCount*Dpi(19): 0; -} diff --git a/c/listview.cpp b/c/listview.cpp new file mode 100644 index 0000000..9f24dc3 --- /dev/null +++ b/c/listview.cpp @@ -0,0 +1,76 @@ +#include <windows.h> +#include <commctrl.h> +#include <uxtheme.h> + +#include "resource.h" +#include "defs.h" + +extern HFONT g_hfNormal; +extern HWND g_hWnd; +static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); + +void +ListView::Create(HMENU hMenu, DWORD dwStyle) +{ + m_hWnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + WC_LISTVIEW, + TEXT(""), + dwStyle + |WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS, + 0, 0, 0, 0, + g_hWnd, hMenu, GetModuleHandle(NULL), this + ); + + if (SetProp(m_hWnd, TEXT("this"), (HANDLE)this)) + m_prevProc = (WNDPROC)SetWindowLongPtr(m_hWnd, + GWLP_WNDPROC, (LONG_PTR)::WndProc); + + ListView_SetExtendedListViewStyle(m_hWnd, LVS_EX_FULLROWSELECT); + + SendMessage(m_hWnd, WM_SETFONT, (WPARAM)g_hfNormal, MAKELPARAM(FALSE, 0)); +} + +/* Naively calculate height of list view. */ +int +ListView::Height(int bHeader) +{ + int iCount; + iCount = ListView_GetItemCount(m_hWnd); + return iCount? Dpi(bHeader? 27: 4)+iCount*Dpi(19): 0; +} + +HWND +ListView::HWnd() +{ + return m_hWnd; +} + +LRESULT CALLBACK +ListView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) { + case HDN_ENDTRACK: + UpdateLayout(); + return TRUE; + } + break; + } + + return CallWindowProc(m_prevProc, hWnd, uMsg, wParam, lParam); +} + +static LRESULT CALLBACK +WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_DESTROY: + RemoveProp(hWnd, TEXT("this")); + break; + } + + ListView *lpThis = (ListView *)GetProp(hWnd, TEXT("this")); + return lpThis? lpThis->WndProc(hWnd, uMsg, wParam, lParam): FALSE; +} @@ -6,20 +6,23 @@ #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; +EpisodeListView g_elv; +DataListView g_dlv; + +atom_t g_aThread; +char g_szLimitScreenwriter[64] = {0}; +HFONT g_hfNormal; +HFONT g_fBold; +HMENU g_hPopupMenu; +HWND g_hFocus; +HWND g_hWnd; +HWND g_hWndStatus; +int g_bViewTVOriginal = 1; +int g_bViewWatched = 1; +int g_bThread = 0; +int g_iDPI = -1; +static int g_bThemes; +static int g_cxVScroll; static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); static HWND CreateStatusBar(HWND, HINSTANCE); @@ -41,12 +44,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, /* Set constant values. */ hModule = LoadLibrary(TEXT("uxtheme.dll")); - BThemes = hModule && GetProcAddress(hModule,"SetWindowTheme"); + g_bThemes = hModule && GetProcAddress(hModule,"SetWindowTheme"); if (hModule) FreeLibrary(hModule); - CxVScroll = GetSystemMetrics(SM_CXVSCROLL); + g_cxVScroll = GetSystemMetrics(SM_CXVSCROLL); /* Initialize Prolog. */ - argv[0] = "EpisodeBrowser"; + argv[0] = (char *)"EpisodeBrowser"; argv[1] = NULL; tszErr = TEXT("Could not initialize Prolog."); if (!PL_initialise(1, argv)) goto f; @@ -59,8 +62,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, tszErr = TEXT("Could not initialize common controls."); if (!InitCommonControlsEx(&icc)) goto f; - HPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU)); - HPopupMenu = GetSubMenu(HPopupMenu, 0); + g_hPopupMenu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_POPUPMENU)); + g_hPopupMenu = GetSubMenu(g_hPopupMenu, 0); memset(&wc, 0, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); @@ -86,13 +89,13 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, ); tszErr = TEXT("Could not create main window."); if (!hWnd) goto f; - HWndStatus = CreateStatusBar(hWnd, hInstance); + g_hWndStatus = CreateStatusBar(hWnd, hInstance); ShowWindow(hWnd, nCmdShow); /* Populate episode list view. */ Pl("track_episodes", "update_tracked_episodes", ""); - ElvUpdate(); - ElvSelectFocus(); + g_elv.Update(); + g_elv.SelectFocus(); while (GetMessage(&msg, NULL, 0, 0) > 0) { if (IsDialogMessage(hWnd, &msg)) continue; @@ -114,36 +117,35 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_CREATE: { HMODULE hModule; - FARPROC GetDpiForWindow; - extern HWND HWnd, HElv; - HWnd = hWnd; - IDPI = 96; + UINT (*GetDpiForWindow)(HWND); + g_hWnd = hWnd; + g_iDPI = 96; hModule = LoadLibrary(TEXT("User32.dll")); - if (hModule && (GetDpiForWindow = GetProcAddress(hModule, "GetDpiForWindow"))) { - IDPI = GetDpiForWindow(HWnd); + if (hModule && (GetDpiForWindow = (UINT (*)(HWND))GetProcAddress(hModule, "GetDpiForWindow"))) { + g_iDPI = GetDpiForWindow(g_hWnd); FreeLibrary(hModule); } SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(400), SWP_NOMOVE); - if (Pl("cfg","get_view_watched","i",&BViewWatched)) + if (Pl("cfg","get_view_watched","i",&g_bViewWatched)) CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED, - BViewWatched? MF_CHECKED: MF_UNCHECKED); - if (Pl("cfg","get_view_tv_original","i",&BViewTVOriginal)) + g_bViewWatched? MF_CHECKED: MF_UNCHECKED); + if (Pl("cfg","get_view_tv_original","i",&g_bViewTVOriginal)) CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL, - BViewTVOriginal? MF_CHECKED: MF_UNCHECKED); + g_bViewTVOriginal? MF_CHECKED: MF_UNCHECKED); { char *sz; if (!Pl("cfg","get_limit_screenwriter","s",&sz)) goto s; - strcpy_s(SzLimitScreenwriter, - sizeof(SzLimitScreenwriter), sz); + strcpy_s(g_szLimitScreenwriter, + sizeof(g_szLimitScreenwriter), sz); CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS, - SzLimitScreenwriter[0]? MF_UNCHECKED: MF_CHECKED); + g_szLimitScreenwriter[0]? MF_UNCHECKED: MF_CHECKED); } s: SetupFonts(); - DlvCreate(); - ElvCreate(); + g_dlv.Create(); + g_elv.Create(); UpdateTheme(); - SetFocus(HElv); + SetFocus(g_elv.HWnd()); break; } case WM_CLOSE: @@ -152,23 +154,23 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_DESTROY: { LVITEM lvi; - extern HWND HElv; + HWND hElv; + hElv = g_elv.HWnd(); lvi.mask = LVIF_PARAM; - if ((lvi.iItem=ListView_GetNextItem(HElv,-1,LVNI_FOCUSED)) != -1 - && ListView_GetItem(HElv, &lvi)) + 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); + SendMessage(g_hWndStatus, WM_SIZE, wParam, lParam); UpdateLayout(); break; case WM_GETMINMAXINFO: { LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; - extern HWND HDlv; - lpMMI->ptMinTrackSize.y = LvHeight(HDlv, 0)+80; + lpMMI->ptMinTrackSize.y = g_dlv.Height(0)+80; break; } case WM_THEMECHANGED: @@ -178,7 +180,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPRECT lpr; lpr = (LPRECT)lParam; - IDPI = HIWORD(wParam); + g_iDPI = HIWORD(wParam); SetWindowPos(hWnd, NULL, lpr->left, lpr->top, lpr->right-lpr->left, @@ -190,19 +192,19 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: switch (wParam) { case WA_INACTIVE: - HFocus = GetFocus(); + g_hFocus = GetFocus(); break; case WA_ACTIVE: case WA_CLICKACTIVE: - SetFocus(HFocus); + SetFocus(g_hFocus); Pl("track_episodes","update_tracked_episodes",""); - ElvRedraw(); + g_elv.Redraw(); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_EPISODELISTVIEW: - return ElvHandleNotify(lParam); + return g_elv.HandleNotify(lParam); } break; case WM_TIMER: @@ -210,9 +212,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDT_TIMER: { static int i = 0; - if (Pl("episode_data","thread_running","A",AThread)) { + if (Pl("episode_data","thread_running","A",g_aThread)) { i = (i+1)%4; - SendMessage(HWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)(i==0? TEXT("."): i==1? TEXT(".."): i==2? TEXT("..."): @@ -220,7 +222,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else { i = 0; KillTimer(hWnd, IDT_TIMER); - ElvUpdate(); + g_elv.Update(); } break; } @@ -232,19 +234,19 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) PostMessage(hWnd, WM_CLOSE, 0, 0); break; case IDM_FILE_REFRESH: - ElvUpdate(); + g_elv.Update(); break; case IDM_FILE_FETCH_DATA: - if (BThread) break; - Pl("episode_data","thread_create","Sa","update_episode_data",&AThread); + if (g_bThread) break; + Pl("episode_data","thread_create","Sa","update_episode_data",&g_aThread); goto t; case IDM_FILE_FETCH_SCREENWRITERS: - if (BThread) break; - Pl("episode_data","thread_create","Sa","update_screenwriters",&AThread); + if (g_bThread) break; + Pl("episode_data","thread_create","Sa","update_screenwriters",&g_aThread); t: KillTimer(hWnd, IDT_TIMER); SetTimer(hWnd, IDT_TIMER, 500, NULL); - SendMessage(HWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)TEXT(".")); - BThread = 1; + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)TEXT(".")); + g_bThread = 1; break; case IDM_FILE_ABOUT: DialogBox( @@ -257,61 +259,64 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDM_VIEW_WATCHED: { int iEpFocus; - extern HWND HElv; + HWND hElv; + hElv = g_elv.HWnd(); 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); + g_bViewWatched? MF_UNCHECKED: MF_CHECKED); + g_bViewWatched = !g_bViewWatched; + g_elv.Update(); + Pl("cfg","set_view_watched","I",g_bViewWatched); + iEpFocus = ListView_GetNextItem(hElv, -1, LVNI_FOCUSED); if (iEpFocus == -1) break; - ListView_EnsureVisible(HElv, iEpFocus, TRUE); + ListView_EnsureVisible(hElv, iEpFocus, TRUE); break; } case IDM_VIEW_TV_ORIGINAL: { int iEpFocus; - extern HWND HElv; + HWND hElv; + hElv = g_elv.HWnd(); 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); + g_bViewTVOriginal? MF_UNCHECKED: MF_CHECKED); + g_bViewTVOriginal = !g_bViewTVOriginal; + g_elv.Update(); + Pl("cfg","set_view_tv_original","I",g_bViewTVOriginal); + iEpFocus = ListView_GetNextItem(hElv, -1, LVNI_FOCUSED); if (iEpFocus == -1) break; - ListView_EnsureVisible(HElv, iEpFocus, TRUE); + ListView_EnsureVisible(hElv, iEpFocus, TRUE); break; } case IDM_VIEW_OTHERS: /* Show/hide other screenwriters. */ { int iEpFocus; - extern HWND HElv; - if (SzLimitScreenwriter[0]) { + HWND hElv; + hElv = g_elv.HWnd(); + if (g_szLimitScreenwriter[0]) { CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS, MF_CHECKED); - SzLimitScreenwriter[0] = 0; + g_szLimitScreenwriter[0] = 0; } else { char *sz; LVITEM lvi; - iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED); + 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 (!ListView_GetItem(hElv, &lvi)) break; if (!Pl("episode_data","episode_datum","ISs", lvi.lParam,"Screenwriter",&sz)) break; - strcpy_s(SzLimitScreenwriter, - sizeof(SzLimitScreenwriter), sz); + strcpy_s(g_szLimitScreenwriter, + sizeof(g_szLimitScreenwriter), sz); CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS, MF_UNCHECKED); } - ElvUpdate(); + g_elv.Update(); Pl("cfg","set_limit_screenwriter","S", - SzLimitScreenwriter); - iEpFocus = ListView_GetNextItem(HElv, -1, LVNI_FOCUSED); + g_szLimitScreenwriter); + iEpFocus = ListView_GetNextItem(hElv, -1, LVNI_FOCUSED); if (iEpFocus == -1) break; - ListView_EnsureVisible(HElv, iEpFocus, TRUE); + ListView_EnsureVisible(hElv, iEpFocus, TRUE); break; } case IDM_WATCH_LOCALLY: @@ -334,7 +339,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int iRating; LVITEM lvi; - extern HWND HElv; + HWND hElv; + hElv = g_elv.HWnd(); /* Look through selected items, applying the * selected command to each one. */ @@ -342,8 +348,8 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 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; + hElv, lvi.iItem, LVNI_SELECTED)) != -1) { + if (!ListView_GetItem(hElv, &lvi)) goto b; switch (LOWORD(wParam)) { case IDM_WATCH_LOCALLY: @@ -354,18 +360,18 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case IDM_TOGGLE: Pl("track_episodes","toggle_episode","I",lvi.lParam); - ElvRedraw(); + g_elv.Redraw(); break; case IDM_FORGET: Pl("track_episodes","forget_episode","I",lvi.lParam); Pl("track_episodes","update_tracked_episodes",""); - ElvRedraw(); + g_elv.Redraw(); break; case IDM_LOOKUP: Pl("episode_data","retract_episode","I",lvi.lParam); - ElvUpdateItem(&lvi); - ElvRedraw(); - DlvShowEpisode(lvi.lParam); + g_elv.UpdateItem(&lvi); + g_elv.Redraw(); + g_dlv.ShowEpisode(lvi.lParam); break; case IDM_WIKI: Pl("episode_data","open_episode_wiki","I",lvi.lParam); @@ -403,7 +409,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); - ElvUpdateItem(&lvi); + g_elv.UpdateItem(&lvi); break; } } @@ -419,9 +425,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDM_RATE2: case IDM_RATE1: case IDM_RATE0: - ElvRedraw(); - ElvDoSort(); - ElvShowFocus(); + g_elv.Redraw(); + g_elv.DoSort(); + g_elv.ShowFocus(); } b: break; } @@ -496,14 +502,14 @@ SetupFonts() m.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &m, 0); - HfNormal = CreateFontIndirect(&m.lfMessageFont); + g_hfNormal = CreateFontIndirect(&m.lfMessageFont); FreeLibrary(hModule); } else - HfNormal = GetStockObject(DEFAULT_GUI_FONT); + g_hfNormal = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT)); - GetObject(HfNormal, sizeof(LOGFONT), &lf); + GetObject(g_hfNormal, sizeof(LOGFONT), &lf); lf.lfWeight = FW_BOLD; - HfBold = CreateFontIndirect(&lf); + g_fBold = CreateFontIndirect(&lf); } /***/ @@ -513,36 +519,39 @@ UpdateLayout() { int cxColumn, cyDlv, yStatus; RECT rc, rcStatus; - extern HWND HDlv, HElv; + HWND hDlv, hElv; - GetClientRect(HWnd, &rc); - GetClientRect(HWndStatus, &rcStatus); + hDlv = g_dlv.HWnd(); + hElv = g_elv.HWnd(); + + GetClientRect(g_hWnd, &rc); + GetClientRect(g_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); + SendMessage(hDlv, WM_SETREDRAW, FALSE, 0); + SendMessage(hElv, WM_SETREDRAW, FALSE, 0); + cyDlv = rc.bottom-yStatus-g_dlv.Height(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-g_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); + 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-g_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, + SendMessage(g_hWndStatus, SB_SETPARTS, (WPARAM)sizeof(aParts), (LPARAM)aParts); } } @@ -554,9 +563,12 @@ UpdateTheme() DWORD dwStyle; LPTSTR tszTheme; WORD wAction; - extern HWND HElv, HDlv; + HWND hDlv, hElv; + + hDlv = g_dlv.HWnd(); + hElv = g_elv.HWnd(); - if (!BThemes) return; + if (!g_bThemes) return; if (IsThemeActive()) { dwStyle = LVS_EX_DOUBLEBUFFER; tszTheme = TEXT("Explorer"); @@ -568,14 +580,14 @@ UpdateTheme() } /* Use modern "Explorer" theme. */ - SetWindowTheme(HElv, tszTheme, NULL); - SetWindowTheme(HDlv, tszTheme, NULL); + 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); + 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); + SendMessage(hElv, WM_UPDATEUISTATE, MAKEWPARAM(wAction, UISF_HIDEFOCUS), 0); + SendMessage(hDlv, WM_UPDATEUISTATE, MAKEWPARAM(wAction, UISF_HIDEFOCUS), 0); } @@ -3,12 +3,12 @@ #include <SWI-Prolog.h> #include "defs.h" -static int Plpv(term_t, char *, va_list); -static int Plgv(term_t, char *, va_list); +static int Plpv(term_t, const char *, va_list); +static int Plgv(term_t, const char *, va_list); /* Call Prolog predicate once. */ int -Pl(char *szMod, char *szPred, char *szFmt, ...) +Pl(const char *szMod, const char *szPred, const char *szFmt, ...) { int iArity; term_t t; @@ -36,7 +36,7 @@ f: va_end(vl); /* Put known values in term. */ int -Plp(term_t t, char *szFmt, ...) +Plp(term_t t, const char *szFmt, ...) { int r; va_list vl; @@ -46,7 +46,7 @@ Plp(term_t t, char *szFmt, ...) return r; } int -Plpv(term_t t, char *szFmt, va_list vl) +Plpv(term_t t, const char *szFmt, va_list vl) { int i; for (i = 0; szFmt[i]; i++) { @@ -90,7 +90,7 @@ Plpv(term_t t, char *szFmt, va_list vl) /* Get unknown values from term. */ int -Plg(term_t t, char *szFmt, ...) +Plg(term_t t, const char *szFmt, ...) { int r; va_list vl; @@ -100,7 +100,7 @@ Plg(term_t t, char *szFmt, ...) return r; } int -Plgv(term_t t, char *szFmt, va_list vl) +Plgv(term_t t, const char *szFmt, va_list vl) { int i; for (i = 0; szFmt[i]; i++) { |