winmain.c
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· C语言 代码 · 共 823 行 · 第 1/2 页
C
823 行
void winconvert(pdfapp_t *app, fz_pixmap *image){ int y, x; if (bmpdata) fz_free(bmpdata); bmpstride = ((image->w * 3 + 3) / 4) * 4; bmpdata = fz_malloc(image->h * bmpstride); if (!bmpdata) return; for (y = 0; y < image->h; y++) { char *p = bmpdata + y * bmpstride; char *s = image->samples + y * image->w * 4; for (x = 0; x < image->w; x++) { p[x * 3 + 0] = s[x * 4 + 3]; p[x * 3 + 1] = s[x * 4 + 2]; p[x * 3 + 2] = s[x * 4 + 1]; } }}void invertcopyrect(void){ unsigned char *p; int x0 = gapp.selr.x0 - gapp.panx; int x1 = gapp.selr.x1 - gapp.panx; int y0 = gapp.selr.y0 - gapp.pany; int y1 = gapp.selr.y1 - gapp.pany; int x, y; x0 = CLAMP(x0, 0, gapp.image->w - 1); x1 = CLAMP(x1, 0, gapp.image->w - 1); y0 = CLAMP(y0, 0, gapp.image->h - 1); y1 = CLAMP(y1, 0, gapp.image->h - 1); for (y = y0; y < y1; y++) { p = bmpdata + y * bmpstride + x0 * 3; for (x = x0; x < x1; x++) { p[0] = 255 - p[0]; p[1] = 255 - p[1]; p[2] = 255 - p[2]; p += 3; } } justcopied = 1;}void winblit(){ int x0 = gapp.panx; int y0 = gapp.pany; int x1 = gapp.panx + gapp.image->w; int y1 = gapp.pany + gapp.image->h; RECT r; if (bmpdata) { if (gapp.iscopying || justcopied) invertcopyrect(); dibinf->bmiHeader.biWidth = gapp.image->w; dibinf->bmiHeader.biHeight = -gapp.image->h; dibinf->bmiHeader.biSizeImage = gapp.image->h * bmpstride; SetDIBitsToDevice(hdc, gapp.panx, /* destx */ gapp.pany, /* desty */ gapp.image->w, /* destw */ gapp.image->h, /* desth */ 0, /* srcx */ 0, /* srcy */ 0, /* startscan */ gapp.image->h, /* numscans */ bmpdata, /* pBits */ dibinf, /* pInfo */ DIB_RGB_COLORS /* color use flag */ ); if (gapp.iscopying || justcopied) invertcopyrect(); } /* Grey background */ r.top = 0; r.bottom = gapp.winh; r.left = 0; r.right = x0; FillRect(hdc, &r, bgbrush); r.left = x1; r.right = gapp.winw; FillRect(hdc, &r, bgbrush); r.left = 0; r.right = gapp.winw; r.top = 0; r.bottom = y0; FillRect(hdc, &r, bgbrush); r.top = y1; r.bottom = gapp.winh; FillRect(hdc, &r, bgbrush); /* Drop shadow */ r.left = x0 + 2; r.right = x1 + 2; r.top = y1; r.bottom = y1 + 2; FillRect(hdc, &r, shbrush); r.left = x1; r.right = x1 + 2; r.top = y0 + 2; r.bottom = y1; FillRect(hdc, &r, shbrush);}void winresize(pdfapp_t *app, int w, int h){ ShowWindow(hwndframe, SW_SHOWDEFAULT); w += GetSystemMetrics(SM_CXFRAME) * 2; h += GetSystemMetrics(SM_CYFRAME) * 2; h += GetSystemMetrics(SM_CYCAPTION); SetWindowPos(hwndframe, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);}void winrepaint(pdfapp_t *app){ InvalidateRect(hwndview, NULL, 0);}/* * Event handling */void windocopy(pdfapp_t *app){ HGLOBAL handle; unsigned short *ucsbuf; if (!OpenClipboard(hwndframe)) return; EmptyClipboard(); handle = GlobalAlloc(GMEM_MOVEABLE, 4096 * sizeof(unsigned short)); if (!handle) { CloseClipboard(); return; } ucsbuf = GlobalLock(handle); pdfapp_oncopy(&gapp, ucsbuf, 4096); GlobalUnlock(handle); SetClipboardData(CF_UNICODETEXT, handle); CloseClipboard(); justcopied = 1; /* keep inversion around for a while... */}void winopenuri(pdfapp_t *app, char *buf){ ShellExecute(hwndframe, "open", buf, 0, 0, SW_SHOWNORMAL);}void handlekey(int c){ if (GetCapture() == hwndview) return; if (justcopied) { justcopied = 0; winrepaint(&gapp); } /* translate VK into ascii equivalents */ switch (c) { case VK_F1: c = '?'; break; case VK_ESCAPE: c = 'q'; break; case VK_DOWN: c = 'd'; break; case VK_UP: c = 'u'; break; case VK_LEFT: c = 'p'; break; case VK_RIGHT: c = 'n'; break; case VK_PRIOR: c = 'b'; break; case VK_NEXT: c = ' '; break; } if (c == 'q') exit(0); else if (c == '?' || c == 'h') help(); else pdfapp_onkey(&gapp, c);}void handlemouse(int x, int y, int btn, int state){ if (state != 0 && justcopied) { justcopied = 0; winrepaint(&gapp); } if (state == 1) SetCapture(hwndview); if (state == -1) ReleaseCapture(); pdfapp_onmouse(&gapp, x, y, btn, 0, state);}LRESULT CALLBACKframeproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ switch(message) { case WM_SETFOCUS: PostMessage(hwnd, WM_APP+5, 0, 0); return 0; case WM_APP+5: SetFocus(hwndview); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; case WM_SYSCOMMAND: if (wParam == ID_ABOUT) { help(); return 0; } if (wParam == ID_DOCINFO) { info(); return 0; } break; case WM_SIZE: { // More generally, you should use GetEffectiveClientRect // if you have a toolbar etc. RECT rect; GetClientRect(hwnd, &rect); MoveWindow(hwndview, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE); } return 0; case WM_SIZING: gapp.shrinkwrap = 0; break; case WM_NOTIFY: case WM_COMMAND: return SendMessage(hwndview, message, wParam, lParam); } return DefWindowProc(hwnd, message, wParam, lParam);}LRESULT CALLBACKviewproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static int oldx = 0; static int oldy = 0; int x = (signed short) LOWORD(lParam); int y = (signed short) HIWORD(lParam); switch (message) { case WM_SIZE: if (wParam == SIZE_MINIMIZED) return 0; if (wParam == SIZE_MAXIMIZED) gapp.shrinkwrap = 0; pdfapp_onresize(&gapp, LOWORD(lParam), HIWORD(lParam)); break; /* Paint events are low priority and automagically catenated * so we don't need to do any fancy waiting to defer repainting. */ case WM_PAINT: { //puts("WM_PAINT"); PAINTSTRUCT ps; hdc = BeginPaint(hwnd, &ps); winblit(); hdc = NULL; EndPaint(hwnd, &ps); return 0; } case WM_ERASEBKGND: return 1; // well, we don't need to erase to redraw cleanly /* Mouse events */ case WM_LBUTTONDOWN: SetFocus(hwndview); oldx = x; oldy = y; handlemouse(x, y, 1, 1); return 0; case WM_MBUTTONDOWN: SetFocus(hwndview); oldx = x; oldy = y; handlemouse(x, y, 2, 1); return 0; case WM_RBUTTONDOWN: SetFocus(hwndview); oldx = x; oldy = y; handlemouse(x, y, 3, 1); return 0; case WM_LBUTTONUP: oldx = x; oldy = y; handlemouse(x, y, 1, -1); return 0; case WM_MBUTTONUP: oldx = x; oldy = y; handlemouse(x, y, 2, -1); return 0; case WM_RBUTTONUP: oldx = x; oldy = y; handlemouse(x, y, 3, -1); return 0; case WM_MOUSEMOVE: oldx = x; oldy = y; handlemouse(x, y, 0, 0); return 0; /* Mouse wheel */ case WM_MOUSEWHEEL: if ((signed short)HIWORD(wParam) > 0) handlekey(LOWORD(wParam) & MK_SHIFT ? '+' : 'u'); else handlekey(LOWORD(wParam) & MK_SHIFT ? '-' : 'd'); return 0; /* Keyboard events */ case WM_KEYDOWN: /* only handle special keys */ switch (wParam) { case VK_F1: case VK_LEFT: case VK_UP: case VK_PRIOR: case VK_RIGHT: case VK_DOWN: case VK_NEXT: case VK_ESCAPE: handlekey(wParam); handlemouse(oldx, oldy, 0, 0); /* update cursor */ return 0; } return 1; /* unicode encoded chars, including escape, backspace etc... */ case WM_CHAR: handlekey(wParam); handlemouse(oldx, oldy, 0, 0); /* update cursor */ return 0; } fflush(stdout); /* Pass on unhandled events to Windows */ return DefWindowProc(hwnd, message, wParam, lParam);}int main(int argc, char **argv){ MSG msg; char buf[1024]; char *filename; fz_cpudetect(); fz_accelerate(); pdfapp_init(&gapp); associate(argv[0]); winopen(); if (argc == 2) filename = fz_strdup(argv[1]); else { if (!winfilename(buf, sizeof buf)) exit(0); filename = buf; } pdfapp_open(&gapp, filename); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } pdfapp_close(&gapp); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?