winmain.c

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· C语言 代码 · 共 823 行 · 第 1/2 页

C
823
字号
#include <fitz.h>#include <mupdf.h>#include "pdfapp.h"#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <commdlg.h>#include <shellapi.h>#define ID_ABOUT	0x1000#define ID_DOCINFO	0x1001static HWND hwndframe = NULL;static HWND hwndview = NULL;static HDC hdc;static HBRUSH bgbrush;static HBRUSH shbrush;static BITMAPINFO *dibinf;static HCURSOR arrowcurs, handcurs, waitcurs;static LRESULT CALLBACK frameproc(HWND, UINT, WPARAM, LPARAM);static LRESULT CALLBACK viewproc(HWND, UINT, WPARAM, LPARAM);static int bmpstride = 0;static char *bmpdata = NULL;static int justcopied = 0;static pdfapp_t gapp;/* * Associate PDFView with PDF files. */void associate(char *argv0){    char tmp[256];    char *name = "Adobe PDF Document";    HKEY key, kicon, kshell, kopen, kcmd;    DWORD disp;    /* HKEY_CLASSES_ROOT\.pdf */    if (RegCreateKeyEx(HKEY_CLASSES_ROOT,		".pdf", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &key, &disp))	return;    if (RegSetValueEx(key, "", 0, REG_SZ, "MuPDF", strlen("MuPDF")+1))	return;    RegCloseKey(key);    /* HKEY_CLASSES_ROOT\MuPDF */    if (RegCreateKeyEx(HKEY_CLASSES_ROOT,		"MuPDF", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &key, &disp))	return;    if (RegSetValueEx(key, "", 0, REG_SZ, name, strlen(name)+1))	return;    /* HKEY_CLASSES_ROOT\MuPDF\DefaultIcon */    if (RegCreateKeyEx(key,		"DefaultIcon", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &kicon, &disp))	return;    sprintf(tmp, "%s,1", argv0);    if (RegSetValueEx(kicon, "", 0, REG_SZ, tmp, strlen(tmp)+1))	return;    RegCloseKey(kicon);    /* HKEY_CLASSES_ROOT\MuPDF\Shell\Open\Command */    if (RegCreateKeyEx(key,		"shell", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &kshell, &disp))	return;    if (RegCreateKeyEx(kshell,		"open", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &kopen, &disp))	return;    if (RegCreateKeyEx(kopen,		"command", 0, NULL, REG_OPTION_NON_VOLATILE,		KEY_WRITE, NULL, &kcmd, &disp))	return;    sprintf(tmp, "\"%s\" \"%%1\"", argv0);    if (RegSetValueEx(kcmd, "", 0, REG_SZ, tmp, strlen(tmp)+1))	return;    RegCloseKey(kcmd);    RegCloseKey(kopen);    RegCloseKey(kshell);    RegCloseKey(key);}/* * Dialog boxes */void winwarn(pdfapp_t *app, char *msg){    MessageBoxA(hwndframe, msg, "MuPDF: Warning", MB_ICONWARNING);}void winerror(pdfapp_t *app, fz_error *error){    char msg[4096];    char buf[200];    msg[0] = 0;    while (error)    {	sprintf(buf, "%s:%d: %s(): %s\n", error->file, error->line, error->func, error->msg);	strcat(msg, buf);	error = error->cause;    }    MessageBoxA(hwndframe, msg, "MuPDF: Error", MB_ICONERROR);    exit(1);}int winfilename(char *buf, int len){    OPENFILENAME ofn;    strcpy(buf, "");    memset(&ofn, 0, sizeof(OPENFILENAME));    ofn.lStructSize = sizeof(OPENFILENAME);    ofn.hwndOwner = hwndframe;    ofn.lpstrFile = buf;    ofn.nMaxFile = len;    ofn.lpstrInitialDir = NULL;    ofn.lpstrTitle = "MuPDF: Open PDF file";    ofn.lpstrFilter = "PDF Files (*.pdf)\0*.pdf\0All Files\0*\0\0";    ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;    return GetOpenFileName(&ofn);}static char pd_filename[256] = "The file is encrypted.";static char pd_password[256] = "";static int pd_okay = 0;INT CALLBACKdlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message)    {    case WM_INITDIALOG:	SetDlgItemText(hwnd, 4, pd_filename);	return TRUE;    case WM_COMMAND:	switch(wParam)	{	case 1:	    pd_okay = 1;	    GetDlgItemText(hwnd, 3, pd_password, sizeof pd_password);	    EndDialog(hwnd, 0);	    return TRUE;	case 2:	    pd_okay = 0;	    EndDialog(hwnd, 0);	    return TRUE;	}	break;    }    return FALSE;}char *winpassword(pdfapp_t *app, char *filename){    char buf[124], *s;    strcpy(buf, filename);    s = buf;    if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1;    if (strrchr(s, '/')) s = strrchr(s, '/') + 1;    if (strlen(s) > 32)	strcpy(s + 30, "...");    sprintf(pd_filename, "The file \"%s\" is encrypted.", s);    DialogBox(NULL, "IDD_DLOGPASS", hwndframe, dlogpassproc);    if (pd_okay)	return pd_password;    return NULL;}INT CALLBACKdloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    char buf[256];    pdf_xref *xref = gapp.xref;    fz_obj *obj;    switch(message)    {    case WM_INITDIALOG:	SetDlgItemTextA(hwnd, 0x10, gapp.filename);	sprintf(buf, "PDF %g", xref->version);	SetDlgItemTextA(hwnd, 0x11, buf);	if (xref->crypt)	{	    sprintf(buf, "Standard %d bit RC4", xref->crypt->len * 8);	    SetDlgItemTextA(hwnd, 0x12, buf);	    strcpy(buf, "");	    if (xref->crypt->p & (1 << 2))		strcat(buf, "print, ");	    if (xref->crypt->p & (1 << 3))		strcat(buf, "modify, ");	    if (xref->crypt->p & (1 << 4))		strcat(buf, "copy, ");	    if (xref->crypt->p & (1 << 5))		strcat(buf, "annotate, ");	    if (strlen(buf) > 2)		buf[strlen(buf)-2] = 0;	    else		strcpy(buf, "none");	    SetDlgItemTextA(hwnd, 0x13, buf);	}	else	{	    SetDlgItemTextA(hwnd, 0x12, "None");	    SetDlgItemTextA(hwnd, 0x13, "n/a");	}	if (!xref->info)	    return TRUE;#define SETUCS(ID) \	{ \	    fz_error *error; \		unsigned short *ucs; \		error = pdf_toucs2(&ucs, obj); \		if (!error) \		{ \		    SetDlgItemTextW(hwnd, ID, ucs); \			fz_free(ucs); \		} \	}	if ((obj = fz_dictgets(xref->info, "Title")))		SETUCS(0x20)	if ((obj = fz_dictgets(xref->info, "Author")))		SETUCS(0x21)	if ((obj = fz_dictgets(xref->info, "Subject")))		SETUCS(0x22)	if ((obj = fz_dictgets(xref->info, "Keywords")))	SETUCS(0x23)	if ((obj = fz_dictgets(xref->info, "Creator")))		SETUCS(0x24)	if ((obj = fz_dictgets(xref->info, "Producer")))	SETUCS(0x25)	if ((obj = fz_dictgets(xref->info, "CreationDate")))	SETUCS(0x26)	if ((obj = fz_dictgets(xref->info, "ModDate")))		SETUCS(0x27)	return TRUE;    case WM_COMMAND:	EndDialog(hwnd, 0);	return TRUE;    }    return FALSE;}void info(){    DialogBox(NULL, "IDD_DLOGINFO", hwndframe, dloginfoproc);}INT CALLBACKdlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message)    {    case WM_INITDIALOG:	SetDlgItemTextA(hwnd, 0x10, gapp.filename);	SetDlgItemTextA(hwnd, 2, "MuPDF is Copyright (C) 2006-2008 artofcode, LLC");	SetDlgItemTextA(hwnd, 3, pdfapp_usage(&gapp));	return TRUE;    case WM_COMMAND:	EndDialog(hwnd, 0);	return TRUE;    }    return FALSE;}void help(){    DialogBox(NULL, "IDD_DLOGABOUT", hwndframe, dlogaboutproc);}/* * Main window */void winopen(){    WNDCLASS wc;    HMENU menu;    RECT r;    /* Create and register window frame class */    wc.style = 0;    wc.lpfnWndProc = frameproc;    wc.cbClsExtra = 0;    wc.cbWndExtra = 0;    wc.hInstance = GetModuleHandle(NULL);    wc.hIcon = LoadIcon(wc.hInstance, "IDI_ICONAPP");    wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = NULL;    wc.lpszMenuName = NULL;    wc.lpszClassName = "FrameWindow";    assert(RegisterClass(&wc) && "Register window class");    /* Create and register window view class */    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = viewproc;    wc.cbClsExtra = 0;    wc.cbWndExtra = 0;    wc.hInstance = GetModuleHandle(NULL);    wc.hIcon = NULL;    wc.hCursor = NULL;    wc.hbrBackground = NULL;    wc.lpszMenuName = NULL;    wc.lpszClassName = "ViewWindow";    assert(RegisterClass(&wc) && "Register window class");    /* Get screen size */    SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);    gapp.scrw = r.right - r.left;    gapp.scrh = r.bottom - r.top;    /* Create cursors */    arrowcurs = LoadCursor(NULL, IDC_ARROW);    handcurs = LoadCursor(NULL, IDC_HAND);    waitcurs = LoadCursor(NULL, IDC_WAIT);    /* And a background color */    bgbrush = CreateSolidBrush(RGB(0x70,0x70,0x70));    shbrush = CreateSolidBrush(RGB(0x40,0x40,0x40));    /* Init DIB info for buffer */    dibinf = malloc(sizeof(BITMAPINFO) + 12);    assert(dibinf != NULL);    dibinf->bmiHeader.biSize = sizeof(dibinf->bmiHeader);    dibinf->bmiHeader.biPlanes = 1;    dibinf->bmiHeader.biBitCount = 24;    dibinf->bmiHeader.biCompression = BI_RGB;    dibinf->bmiHeader.biXPelsPerMeter = 2834;    dibinf->bmiHeader.biYPelsPerMeter = 2834;    dibinf->bmiHeader.biClrUsed = 0;    dibinf->bmiHeader.biClrImportant = 0;    dibinf->bmiHeader.biClrUsed = 0;    /* Create window */    hwndframe = CreateWindow("FrameWindow", // window class name	    NULL, // window caption	    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,	    CW_USEDEFAULT, CW_USEDEFAULT, // initial position	    300, // initial x size	    300, // initial y size	    0, // parent window handle	    0, // window menu handle	    0, // program instance handle	    0); // creation parameters    hwndview = CreateWindow("ViewWindow", // window class name	    NULL,	    WS_VISIBLE | WS_CHILD,	    CW_USEDEFAULT, CW_USEDEFAULT,	    CW_USEDEFAULT, CW_USEDEFAULT,	    hwndframe, 0, 0, 0);    hdc = NULL;    SetWindowTextA(hwndframe, "MuPDF");    menu = GetSystemMenu(hwndframe, 0);    AppendMenu(menu, MF_SEPARATOR, 0, NULL);    AppendMenu(menu, MF_STRING, ID_ABOUT, "About MuPDF...");    AppendMenu(menu, MF_STRING, ID_DOCINFO, "Document Properties...");    SetCursor(arrowcurs);}void wincursor(pdfapp_t *app, int curs){    if (curs == ARROW)	SetCursor(arrowcurs);    if (curs == HAND)	SetCursor(handcurs);    if (curs == WAIT)	SetCursor(waitcurs);}void wintitle(pdfapp_t *app, char *title){    unsigned short wide[256], *dp;    char *sp;    int rune;    dp = wide;    sp = title;    while (*sp && dp < wide + 255)    {	sp += chartorune(&rune, sp);	*dp++ = rune;    }    *dp = 0;    SetWindowTextW(hwndframe, wide);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?