📄 hgraf_win32.c
字号:
} DeleteDC(dc); DeleteObject(bm); ReleaseDC(theWindow,tdc); Dispose(&gcheap,data);}/* EXPORT->HFlush: flush any pending draw operations */void HFlush(void){}/* EXPORT-> HSpoolGraf: start saving an image of window in fname *//* must be balanced by a call to HEndSpoolGraf() */void HSpoolGraf(char *fname){ int wmm,hmm; /* width and height in millimeters */ int wpx,hpx; /* width and height in pixels */ char *description = "Created by HGraf"; RECT r; HDC dc = GetDC(theWindow); int er; wmm = GetDeviceCaps(dc, HORZSIZE); hmm = GetDeviceCaps(dc, VERTSIZE); wpx = GetDeviceCaps(dc, HORZRES); hpx = GetDeviceCaps(dc, VERTRES); r.left = (ClientRect.left * wmm * 100)/wpx; r.top = (ClientRect.top * hmm * 100)/hpx; r.right = (ClientRect.right * wmm * 100)/wpx; r.bottom = (ClientRect.bottom * hmm * 100)/hpx; DCSaved = memDC; memDC = CreateEnhMetaFile(dc,fname,&r,description); er = GetLastError(); ReleaseDC(theWindow,dc); WritingToMeta = TRUE;}/* EXPORT-> HEndSpoolGraf: close file opened in HSpoolGraf() *//* It is recommended to redraw the window after this call. */void HEndSpoolGraf(){ WritingToMeta = FALSE; CloseEnhMetaFile(memDC); memDC = DCSaved;}/* EXPORT->HDumpGraf: dump a BMP image of current display into fname */void HDumpGraf(char *fname){ BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BitmapHeader; BITMAPINFO *Info; int ColorTableSize; int ImageSize; FILE *fp; char *img; HDC dc = GetDC(theWindow); HBITMAP temp = CreateCompatibleBitmap(memDC,1,1); SelectObject(memDC,temp); /* retrieve information about the bitmap */ BitmapHeader.biSize = sizeof(BITMAPINFOHEADER); BitmapHeader.biBitCount = 0; GetDIBits(memDC,theBitmap,0,0,NULL,&BitmapHeader,BI_RGB); switch (BitmapHeader.biCompression) { case BI_RGB: if (BitmapHeader.biBitCount > 8) { ColorTableSize = 0; } else { ColorTableSize = BitmapHeader.biClrUsed*sizeof(RGBQUAD); } break; case BI_RLE8: case BI_RLE4: ColorTableSize = BitmapHeader.biClrUsed*sizeof(RGBQUAD); break; case BI_BITFIELDS: ColorTableSize = 3*sizeof(DWORD); } Info = (BITMAPINFO *) New(&gcheap,sizeof(BITMAPINFOHEADER) + ColorTableSize); memcpy(Info,&BitmapHeader,sizeof(BITMAPINFOHEADER)); ImageSize = BitmapHeader.biSizeImage; img = New(&gcheap,ImageSize); GetDIBits(memDC,theBitmap,0,ClientRect.bottom,img,Info,BI_RGB); FileHeader.bfType = 0x4d42; /* 'BM' */ FileHeader.bfSize = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + ImageSize + ColorTableSize; FileHeader.bfReserved1 = FileHeader.bfReserved2 = 0; FileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ColorTableSize; fp = fopen(fname,"wb"); fwrite(&FileHeader,1,sizeof(BITMAPFILEHEADER),fp); fwrite(Info,1,sizeof(BITMAPINFOHEADER) + ColorTableSize,fp); fwrite(img,1,ImageSize,fp); fclose(fp); SelectObject(memDC,theBitmap); DeleteObject(temp); Dispose(&gcheap,Info); Dispose(&gcheap,img);}#define BTN_WAIT 200 /* 200 milliseconds minimum button press */#define BTN_LINE_WIDTH 1 /* the line width for button drawing *//* EXPORT->CreateHButton: create a button object with the specified parameters */HButton *CreateHButton(HButton *btnlst, ButtonId btnid, int x, int y, int w, int h, char *str, HColour fg, HColour bg, void (*action)(void)){ HButton *btn, *btnptr; btn = New(&btnHeap, sizeof(HButton)); /* initialise the fields of the structure */ btn->id = btnid; btn->x = x; btn->y = y; btn->w = w; btn->h = h; btn->str = str; btn->fg = fg; btn->bg = bg; btn->lit = FALSE; btn->active = TRUE; btn->toggle = FALSE; btn->next = NULL; /* append it to the end of the list if the list already exists */ if (btnlst!=NULL){ btnptr = btnlst; while (btnptr->next != NULL) btnptr = btnptr->next; btnptr->next = btn; } btn->action = action; /* return ptr to the newly created button */ return btn;}/* EXPORT->RedrawHButton: readraw a single button object */void RedrawHButton(HButton *btn){ int pad = 2; int x, y, w, h, r, s, pos; HPoint poly[9], shad[4]; char sbuf[256], nullchar = '\0'; x = btn->x; y=btn->y; w=btn->w; h=btn->h; r=3; s=1; /* set up the polygon */ poly[0].x = x; poly[0].y = y+r; poly[1].x = x; poly[1].y = y+h-r; poly[2].x = x+r; poly[2].y = y+h; poly[3].x = x+w-r; poly[3].y = y+h; poly[4].x = x+w; poly[4].y = y+h-r; poly[5].x = x+w; poly[5].y = y+r; poly[6].x = x+w-r; poly[6].y = y; poly[7].x = x+r; poly[7].y = y; poly[8].x = x; poly[8].y = y+r; /* set up the extra lines for the shadow */ shad[0].x = x+r+s; shad[0].y = y+h+s; shad[1].x = x+w-r+s; shad[1].y = y+h+s; shad[2].x = x+w+s; shad[2].y = y+h-r+s; shad[3].x = x+w+s; shad[3].y = y+r+s; if (btn->lit) HSetColour(btn->fg); else HSetColour(btn->bg); HFillPolygon(poly, 9); HSetColour(btn->fg); HDrawLines(poly, 9); HDrawLines(shad, 4); if (btn->active) if (btn->lit) HSetColour(btn->bg); else HSetColour(btn->fg); else HSetGrey(30); strcpy(sbuf, btn->str); pos = strlen(sbuf); while(HTextWidth(sbuf) > (w - 2*pad)) sbuf[--pos]=nullchar; HPrintf(CentreX(x+w/2, sbuf), CentreY(y+h/2, sbuf), "%s", sbuf);}/* EXPORT->RedrawHButtonList: redraw the whole list of buttons */void RedrawHButtonList(HButton *btnlst){ HButton *btnptr; HSetLineWidth(BTN_LINE_WIDTH); for (btnptr=btnlst; btnptr!=NULL; btnptr=btnptr->next) RedrawHButton(btnptr); }/* EXPORT->FindButton: find button given name */HButton *FindButton(HButton *btnlst, ButtonId key){ HButton *btnptr; for (btnptr=btnlst; btnptr!=NULL; btnptr=btnptr->next) if (btnptr->id==key) return btnptr; return NULL;}/* EXPORT->SetActive: set active field in button list */void SetActive(HButton *btnlst, Boolean active){ HButton *btnptr; for (btnptr=btnlst; btnptr!=NULL; btnptr=btnptr->next) btnptr->active = active;}/* EXPORT->CheckButtonList: find within which button the point(x,y) is */HButton *CheckButtonList(HButton *btnlst, int x, int y){ HButton *btn; for (btn=btnlst; btn!=NULL; btn=btn->next) if (IsInRect(x, y, btn->x, btn->y, btn->x + btn->w, btn->y + btn->h) && btn->active) return btn; return NULL; }/* EXPORT->SetButtonLit: show button press */void SetButtonLit(HButton *btn, Boolean lit){ if (btn->lit != lit){ btn->lit = lit; RedrawHButton(btn); }}/* EXPORT->TrackButtons: tracks the buttons until the mouse button is released */ButtonId TrackButtons(HButton *btnlist, HEventRec hev){ HButton *pressed, *released; Boolean done; pressed = CheckButtonList(btnlist, hev.x, hev.y); if (pressed != NULL){ SetButtonLit(pressed, TRUE); done = FALSE;#ifdef USE_TIMER HFlush(); Timer(BTN_WAIT);#endif do { hev = HGetEvent(TRUE, pressed->action); done = (hev.event==HMOUSEUP); } while (!done); released = CheckButtonList(btnlist, hev.x, hev.y); SetButtonLit(pressed, FALSE); if ( pressed == released) return pressed->id; } return 0;}static void InitGlobals(void){ dispWIDE = GetSystemMetrics(SM_CXSCREEN); dispHIGH = GetSystemMetrics(SM_CYSCREEN); dispDEEP = GetDeviceCaps(memDC,BITSPIXEL); }/* EXPORT-> MakeXGraf: Create and open window, initialization */void MakeXGraf(char *wname, int x, int y, int w, int h, int bw) /* WIN32: bw is ignored. */{ WNDCLASS WindowClass; char sbuf[256], *hgraf = "HGraf"; HDC dc; if (winCreated) HError(6870, "MakeXGraf: Attempt to recreate the graphics window"); WindowClass.hInstance = GetModuleHandle(NULL); WindowClass.lpszClassName = hgraf; WindowClass.lpfnWndProc = HGWinFunc; WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; WindowClass.hIcon = NULL; WindowClass.hCursor = LoadCursor(NULL,IDC_ARROW); WindowClass.lpszMenuName = NULL; WindowClass.cbClsExtra = 0; WindowClass.cbWndExtra = 0; WindowClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); RegisterClass(&WindowClass); strcpy(sbuf, hgraf); strcat(sbuf, ": "); strcat(sbuf, wname); theWindow = CreateWindow(hgraf, sbuf, WS_OVERLAPPEDWINDOW | WS_VISIBLE, x,y, w,h, HWND_DESKTOP, NULL, WindowClass.hInstance, NULL); /* adjust window size so that the client rectangle is the size requested */ /* by the caller of MakeXGraf() --- Win32 interprets w and h as the dimensions */ /* of the overall window. */ GetClientRect(theWindow,&ClientRect); MoveWindow(theWindow,x,y,w+w-ClientRect.right,h+h-ClientRect.bottom,TRUE); GetClientRect(theWindow,&ClientRect); /* Obtain and initialize device contexts */ dc = GetDC(theWindow); memDC = CreateCompatibleDC(dc); SetArcDirection(memDC,AD_COUNTERCLOCKWISE); SetArcDirection(dc,AD_COUNTERCLOCKWISE); SetPolyFillMode(memDC,WINDING); SetPolyFillMode(memDC,WINDING); SetTextAlign(memDC,TA_BASELINE | TA_LEFT); SetTextAlign(dc,TA_BASELINE | TA_LEFT); SetBkMode(memDC,TRANSPARENT); SetBkMode(dc,TRANSPARENT); theBitmap = CreateCompatibleBitmap(dc,w,h); SelectObject(memDC,theBitmap); ReleaseDC(theWindow,dc); CreateHeap(&btnHeap, "Button heap", MHEAP, sizeof(HButton), 1.0, 100, 100); InitGlobals(); InstallColours(); winCreated = TRUE; HSetColour(WHITE); HFillRectangle(0,0,ClientRect.right,ClientRect.bottom);}/* EXPORT->TermHGraf: Terminate Graphics (also called via at_exit) */void TermHGraf(){ if (theBrush) DeleteObject(theBrush); if (thePen) DeleteObject(thePen); if (thinPen) DeleteObject(thinPen); if (theFont) DeleteObject(theFont); if (theBitmap) DeleteObject(theBitmap); DeleteHeap(&btnHeap); DestroyWindow(theWindow);}/********** Win32 specific functions *//* Called by the window manager */LRESULT CALLBACK HGWinFunc(HWND WindowHandle, unsigned int msg, WPARAM wParam, LPARAM lParam){ HDC dc; PAINTSTRUCT ps; switch (msg) { case WM_SIZING: /* for some reason we have to repaint when the window moves */ case WM_MOVING: InvalidateRect(theWindow,&ClientRect,FALSE); return TRUE; case WM_EXITSIZEMOVE: InvalidateRect(theWindow,&ClientRect,FALSE); return 0; case WM_PAINT: dc = BeginPaint(theWindow,&ps); BitBlt(dc,0,0,ClientRect.right,ClientRect.bottom,memDC,0,0,SRCCOPY); EndPaint(theWindow,&ps); return 0; default: return DefWindowProc(WindowHandle, msg, wParam, lParam); }}KeyType HGetKeyType(char c){ switch ((int) c) { case VK_ESCAPE: return ESCKEY; case VK_DELETE: case VK_BACK: return DELKEY; case VK_RETURN: return ENTERKEY; case VK_CONTROL: return CONTROLKEY; case VK_MENU: return COMMANDKEY; case VK_SHIFT: return SHIFTKEY; default: return NORMALKEY; }}/* ------------------------ End of HGraf.win32.c ------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -