#include #include #include #include #include #include #include "resource.h" #define CLASSNAME TEXT("Episode Browser") HFONT g_GUIFont; static int Attach(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 main(int argc, char *argv[]) { char *rgArgs[2]; rgArgs[0] = "episode_browser"; rgArgs[1] = NULL; if (!PL_initialise(1, rgArgs)) PL_halt(1); Attach(); //UpdateList(); //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 r; term_t t; t = PL_new_term_refs(2); r = PL_call_predicate(NULL, PL_Q_NORMAL, PL_predicate("attach", 0, "track_episodes"), t); if (!r) return r; r = PL_call_predicate(NULL, PL_Q_NORMAL, PL_predicate("attach", 0, "episode_data"), t); if (!r) return r; return 1; } HFONT GetGUIFont() { #ifndef WIN9X NONCLIENTMETRICS m; 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(HWND hwnd, int iEpisode) { int r; term_t t; t = PL_new_term_refs(3); if(!PL_put_integer(t+0, iEpisode)) return; r = PL_call_predicate(NULL, PL_Q_NORMAL, PL_predicate("lookup_episode_local", 3, "episode_data"), t); if (!r) return; /* The episode data is a list of unary compounds, * whose functor is the key and whose argument is the value. */ { term_t tHead, tList; tHead = PL_new_term_ref(); tList = PL_copy_term_ref(t+2); while (PL_get_list(tList, tHead, tList)) { atom_t aKey; 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; if (!PL_get_atom_chars(tValue, &szValue)) continue; 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); }