aboutsummaryrefslogtreecommitdiff
path: root/win.c
diff options
context:
space:
mode:
Diffstat (limited to 'win.c')
-rw-r--r--win.c386
1 files changed, 342 insertions, 44 deletions
diff --git a/win.c b/win.c
index 660275d..8764092 100644
--- a/win.c
+++ b/win.c
@@ -1,15 +1,25 @@
#include <windows.h>
-#include <SWI-Prolog.h>
+#include <TCHAR.H>
+#include <commctrl.h>
#include <stdio.h>
+#include <string.h>
+#include <SWI-Prolog.h>
+#include "resource.h"
+
+#define CLASSNAME TEXT("Episode Browser")
+
+HFONT g_GUIFont;
static int Attach(void);
-static void ShowEpisode(int);
-static void UpdateList(void);
+static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
+static HFONT GetGUIFont();
+static void UpdateName(HWND, int);
+static void UpdateList(HWND);
+static void ShowEpisode(HWND, int);
+static TCHAR *TSZFromSZ(int, char *);
+static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
/*
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR lpCmdLine, INT nCmdShow)
-*/
int main(int argc, char *argv[])
{
char *rgArgs[2];
@@ -22,13 +32,189 @@ int main(int argc, char *argv[])
Attach();
//UpdateList();
- ShowEpisode(400);
+ //ShowEpisode(400);
PL_halt(0);
}
+*/
+
+int WINAPI
+WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, INT nCmdShow)
+{
+ char *rgArgs[2];
+ HWND hwnd;
+ MSG msg;
+ INITCOMMONCONTROLSEX icc;
+ WNDCLASSEX wc;
+
+ /* Initialize Prolog. */
+
+ rgArgs[0] = "episode_browser";
+ rgArgs[1] = NULL;
+
+ if (!PL_initialise(1, rgArgs))
+ PL_halt(1);
+
+ Attach();
+
+ /* Create window. */
+
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&icc);
+
+ g_GUIFont = GetGUIFont();
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = 0;
+ wc.lpfnWndProc = WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ 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 = CLASSNAME;
+ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+
+ RegisterClassEx(&wc);
+
+ hwnd = CreateWindowEx(
+ 0,
+ CLASSNAME,
+ TEXT("Episode Browser"),
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, /* Position */
+ 510, 300, /* Size */
+ NULL, /* Parent window */
+ NULL, /* Menu */
+ hInstance,
+ NULL
+ );
+
+ if (!hwnd)
+ return 0;
+
+ ShowWindow(hwnd, nCmdShow);
+
+ while (GetMessage(&msg, NULL, 0, 0) > 0) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
+
+LRESULT CALLBACK
+WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg) {
+ case WM_CLOSE:
+ DestroyWindow(hwnd);
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case ID_FILE_EXIT:
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ break;
+ case ID_FILE_ABOUT:
+ DialogBox(
+ GetModuleHandle(NULL),
+ MAKEINTRESOURCE(IDD_ABOUT),
+ hwnd,
+ AboutDlgProc
+ );
+ break;
+ }
+ break;
+ case WM_CREATE:
+ {
+ HWND hListView;
+ LVCOLUMN lvc;
+
+ hListView = CreateWindowEx(
+ 0,
+ WC_LISTVIEW,
+ TEXT(""),
+ WS_CHILD|WS_VISIBLE|WS_VSCROLL|LVS_REPORT,
+ 0, 0, 100, 100,
+ hwnd,
+ (HMENU)IDC_LISTVIEW,
+ GetModuleHandle(NULL),
+ NULL
+ );
+
+ SendMessage(hListView,LVM_SETEXTENDEDLISTVIEWSTYLE,
+ 0, LVS_EX_FULLROWSELECT);
+
+ SendMessage(hListView, WM_SETFONT,
+ (WPARAM)g_GUIFont, MAKELPARAM(FALSE, 0));
+
+ lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
+
+ lvc.iSubItem = 0;
+ lvc.pszText = TEXT("#");
+ lvc.cx = 40;
+ ListView_InsertColumn(hListView, 0, &lvc);
+
+ lvc.iSubItem = 1;
+ lvc.pszText = TEXT("Title");
+ lvc.cx = 500;
+ ListView_InsertColumn(hListView, 1, &lvc);
+
+ UpdateList(hListView);
+ }
+ break;
+ case WM_SIZE:
+ {
+ HWND hListView;
+ RECT rc;
+
+ GetClientRect(hwnd, &rc);
+ hListView = GetDlgItem(hwnd, IDC_LISTVIEW);
+ MoveWindow(hListView, 0, 0,
+ rc.right, rc.bottom,
+ TRUE);
+ }
+ 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_INITDIALOG:
+ return TRUE;
+ 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;
+}
/* Attach persistent databases. */
-int Attach()
+int
+Attach()
{
int r;
term_t t;
@@ -47,53 +233,40 @@ int Attach()
return 1;
}
-/* Update episode list. */
-void UpdateList()
+HFONT
+GetGUIFont()
{
- term_t t;
- qid_t q;
-
- t = PL_new_term_refs(2);
- PL_call_predicate(NULL, PL_Q_NORMAL,
- PL_predicate("update_tracked_episodes", 0, "track_episode"),
- t);
-
- q = PL_open_query(NULL, PL_Q_NORMAL,
- PL_predicate("episode_file", 2, "local_episodes"),
- t);
-
- while (PL_next_solution(q)) {
- char *sFile;
- int nEpisode;
-
- if (!PL_get_integer(t+0, &nEpisode))
- goto close;
- if (!PL_get_atom_chars(t+1, &sFile))
- goto close;
- printf("%d: %s\n", nEpisode, sFile);
- }
+#ifndef WIN9X
+ NONCLIENTMETRICS m;
-close:
- PL_close_query(q); /* Or PL_cut_query? */
+ m.cbSize = sizeof(NONCLIENTMETRICS);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
+ &m, 0);
+ return CreateFontIndirect(&m.lfMessageFont);
+#else
+ return GetStockObject(DEFAULT_GUI_FONT);
+#endif
}
/* Show episode data. */
-void ShowEpisode(int nEpisode)
+void
+ShowEpisode(HWND hwnd, int iEpisode)
{
int r;
term_t t;
t = PL_new_term_refs(3);
- if(!PL_put_integer(t+0, nEpisode))
+ if(!PL_put_integer(t+0, iEpisode))
return;
r = PL_call_predicate(NULL, PL_Q_NORMAL,
- PL_predicate("lookup_episode_local", 3, "episode_data"),
+ PL_predicate("lookup_episode_local", 3, "episode_data"),
t);
- if (!r) return;
+ if (!r)
+ return;
/* The episode data is a list of unary compounds,
- * whose name is the key and whose value is the value. */
+ * whose functor is the key and whose argument is the value. */
{
term_t tHead, tList;
@@ -103,20 +276,145 @@ void ShowEpisode(int nEpisode)
while (PL_get_list(tList, tHead, tList)) {
atom_t aKey;
- const char *sKey;
- char *sValue;
+ const char *szKey;
+ char *szValue;
term_t tValue;
size_t iArity;
if (!PL_get_name_arity(tHead, &aKey, &iArity))
continue;
+ szKey = PL_atom_chars(aKey);
+
if (!PL_get_arg(1, tHead, tValue))
continue;
- sKey = PL_atom_chars(aKey);
- if(!PL_get_atom_chars(tValue, &sValue))
+ if (!PL_get_atom_chars(tValue, &szValue))
continue;
- printf("%s/%d: %s\n", sKey, iArity, sValue);
+ printf("%s/%d: %s\n", szKey, iArity, szValue);
}
}
}
+
+TCHAR *
+TSZFromSZ(int iCp, char *sz)
+{
+ TCHAR *tsz;
+
+#ifdef UNICODE
+ int cb;
+
+ cb = MultiByteToWideChar(iCp, 0, sz, -1, NULL, 0);
+ tsz = malloc(cb*sizeof(wchar_t));
+ if (!tsz)
+ return NULL;
+ if (!MultiByteToWideChar(iCp, 0, sz, -1, tsz, cb))
+ return NULL;
+#else
+ tsz = malloc(strlen(sz)+1);
+ if (!tsz)
+ return NULL;
+ strcpy(tsz, sz);
+#endif
+
+ return tsz;
+}
+
+/* Update episode name. */
+void
+UpdateName(HWND hwnd, int iEpisode)
+{
+ char *szName;
+ term_t t;
+
+ t = PL_new_term_refs(3);
+ if (!PL_put_integer(t+0, iEpisode))
+ return;
+
+ PL_call_predicate(NULL, PL_Q_NORMAL,
+ PL_predicate("lookup_episode", 3, "episode_data"),
+ t);
+
+ if (!PL_get_atom_chars(t+1, &szName))
+ return;
+
+ printf("%s\n", szName);
+}
+
+/* Update episode list. */
+void
+UpdateList(HWND hListView)
+{
+ LVITEM lviEpisode, lviName;
+ qid_t q;
+ term_t t;
+
+ lviEpisode.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
+ lviEpisode.state = 0;
+ lviEpisode.stateMask = 0;
+
+ lviName.mask = LVIF_TEXT;
+
+ t = PL_new_term_refs(2);
+ PL_call_predicate(NULL, PL_Q_NORMAL,
+ PL_predicate("update_tracked_episodes", 0, "track_episode"),
+ t);
+
+ q = PL_open_query(NULL, PL_Q_NORMAL,
+ PL_predicate("episode_file", 2, "local_episodes"),
+ t);
+
+ for (int i = 0; PL_next_solution(q); i++) {
+ char *szName;
+ int cb, iEpisode, iItem, r;
+ TCHAR *tszEpisode, *tszName;
+ term_t t2;
+
+ /* Lookup episode name. */
+
+ if (!PL_get_integer(t+0, &iEpisode))
+ goto close;
+
+ t2 = PL_new_term_refs(3);
+ if(!PL_put_integer(t2+0, iEpisode))
+ return;
+
+ r = PL_call_predicate(NULL, PL_Q_NORMAL,
+ PL_predicate("lookup_episode_local", 3, "episode_data"),
+ t2);
+
+ /* Format episode, name strings. */
+
+ tszName = NULL;
+ if (r && PL_get_atom_chars(t2+1, &szName)) {
+ tszName = TSZFromSZ(CP_UTF8, szName);
+ if (!tszName)
+ continue;
+ }
+
+ cb = 100;
+ tszEpisode = malloc(cb*sizeof(TCHAR));
+ if (!tszEpisode)
+ continue;
+ _stprintf_s(tszEpisode, cb, TEXT("%d"),
+ iEpisode);
+
+ /* Insert item. */
+
+ lviEpisode.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
+ lviEpisode.iItem = i;
+ lviEpisode.iSubItem = 0;
+ lviEpisode.pszText = tszEpisode;
+ lviEpisode.lParam = iEpisode;
+ ListView_InsertItem(hListView, &lviEpisode);
+
+ if (tszName) {
+ lviName.iItem = i;
+ lviName.iSubItem = 1;
+ lviName.pszText = tszName;
+ ListView_SetItem(hListView, &lviName);
+ }
+ }
+
+close:
+ PL_close_query(q);
+}