|
void sheet_refresh(HDC hdc, RECT rect) { HBITMAP hbmpMem = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top); HDC hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hbmpMem);
HDC hdcBmp = CreateCompatibleDC(hdc); RECT rcDraw, rcSheet; int z; for (z = 0; z <= shtctl->top; z++) { rcSheet.left = shtctl->sheets[z]->x; rcSheet.top = shtctl->sheets[z]->y; rcSheet.right = rcSheet.left + shtctl->sheets[z]->width; rcSheet.bottom = rcSheet.top + shtctl->sheets[z]->height; if (!IntersectRect(&rcDraw, &rcSheet, &rect)) continue; RECT rcDrawMem = rcDraw; OffsetRect(&rcDrawMem, -rect.left, -rect.top); SelectObject(hdcBmp, shtctl->sheets[z]->hbmp); if (shtctl->sheets[z]->invisible_color == -1) BitBlt(hdcMem, rcDrawMem.left, rcDrawMem.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, hdcBmp, rcDraw.left - rcSheet.left, rcDraw.top - rcSheet.top, SRCCOPY); else TransparentBlt(hdcMem, rcDrawMem.left, rcDrawMem.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, hdcBmp, rcDraw.left - rcSheet.left, rcDraw.top - rcSheet.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, shtctl->sheets[z]->invisible_color); } BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcMem, 0, 0, SRCCOPY); DeleteDC(hdcBmp); DeleteDC(hdcMem); DeleteObject(hbmpMem); }
|
|
#include <tchar.h> #include <Windows.h> #include "graphic.h" #include "memman.h" #include "sheet.h" extern HINSTANCE hInst; extern HWND hWnd; extern SHEET *sht_back, *sht_cursor; SHTCTL *shtctl; SHEET *create_window(LPCTSTR title, int x, int y, int width, int height, HDC *hdc, COLORREF invisible_color) { SHEET *win = sheet_alloc(); win->title = title; sheet_create_bitmap(win, width, height, -1); HDC hdcWin = sheet_begin_paint(win); draw_window(hdcWin, width, height, title); if (hdc == NULL) sheet_end_paint(win, hdcWin); else *hdc = hdcWin; sheet_move(win, x, y); sheet_setz(win, shtctl->top); return win; } void sheet_active(SHEET *sht) { if (shtctl->active == sht) return; HDC hdc; if (sht != sht_back && sht != sht_cursor) { hdc = sheet_begin_paint(sht); draw_window_titlebar(hdc, sht->width, sht->title, true); sheet_end_paint(sht, hdc); } if (shtctl->active != NULL && shtctl->active != sht_back && shtctl->active != sht_cursor) { // not screen, not mouse hdc = sheet_begin_paint(shtctl->active); draw_window_titlebar(hdc, shtctl->active->width, shtctl->active->title, false); sheet_end_paint(shtctl->active, hdc); } caret_hide(); shtctl->active = sht; caret_show(); if (sht != sht_back && sht != sht_cursor) { if (sht->z != shtctl->top - 1) sheet_top(sht); } } SHEET *sheet_alloc(LPVOID param) { SHEET *sht; int i; for (i = 0; i < MAX_SHEETS; i++) { if (shtctl->sheets0[i].flags == 0) { sht = &shtctl->sheets0[i]; sht->flags = SHEET_USE; sht->z = -1; // hide sht->param = param; sheet_remove_caret(sht); return sht; } } return NULL; } /* 返回一个绘制图层的HDC */ HDC sheet_begin_paint(SHEET *sht) { HDC hdc = GetDC(hWnd); HDC hdcMem = CreateCompatibleDC(hdc); ReleaseDC(hWnd, hdc); DeleteDC(hdc); SelectObject(hdcMem, sht->hbmp); SelectObject(hdcMem, GetStockObject(NULL_PEN)); return hdcMem; } void sheet_create_bitmap(SHEET *sht, int width, int height, COLORREF invisible_color) { HDC hdc = GetDC(hWnd); sheet_create_bitmap(sht, hdc, width, height, invisible_color); ReleaseDC(hWnd, hdc); DeleteDC(hdc); } void sheet_create_bitmap(SHEET *sht, HDC hdc, int width, int height, COLORREF invisible_color) { sht->hbmp = CreateCompatibleBitmap(hdc, width, height); sheet_setinfo(sht, width, height, invisible_color); } /* 若要指定hdc, 请改用draw_text函数并手动完成刷新(或者刷新整个图层也行) */ SIZE sheet_draw_text(SHEET *sht, int x, int y, COLORREF text_color, COLORREF bk_color, LPCTSTR str, int refresh_width) { HDC hdc = sheet_begin_paint(sht); int len = _tcslen(str); SIZE size = draw_text(hdc, x, y, text_color, bk_color, str, refresh_width); sheet_end_paint(sht, hdc, x, y, (refresh_width == 0) ? (x + size.cx) : (x + refresh_width), y + size.cy); return size; } /* 结束绘制并刷新整个图层 */ void sheet_end_paint(SHEET *sht, HDC hdcMem) { DeleteDC(hdcMem); sheet_refresh(sht); } /* 结束绘制并刷新图层中的指定区域 */ void sheet_end_paint(SHEET *sht, HDC hdcMem, int x0, int y0, int x1, int y1) { sheet_end_paint(sht, hdcMem, make_rect(x0, y0, x1, y1)); } void sheet_end_paint(SHEET *sht, HDC hdcMem, RECT rect) { DeleteDC(hdcMem); sheet_refresh(sht, rect); } /* 删除图层 */ void sheet_free(SHEET *sht) { if (shtctl->active == sht) shtctl->active = NULL; if (sht->z >= 0) sheet_setz(sht, -1); DeleteObject(sht->hbmp); sht->hbmp = NULL; sht->flags = 0; } void sheet_load_bitmap(SHEET *sht, int iBmp, COLORREF invisible_color) { BITMAP bmp; sht->hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(iBmp)); GetObject(sht->hbmp, sizeof(bmp), &bmp); sheet_setinfo(sht, bmp.bmWidth, bmp.bmHeight, invisible_color); } void sheet_move(SHEET *sht, int x, int y) { int old_x = sht->x; int old_y = sht->y; sht->x = x; sht->y = y; if (sht->z >= 0) { sheet_refresh(old_x, old_y, old_x + sht->width, old_y + sht->height); sheet_refresh(x, y, x + sht->width, y + sht->height); } } /* 刷新整个画面 */ void sheet_refresh(void) { RECT rect; GetClientRect(hWnd, &rect); InvalidateRect(hWnd, &rect, FALSE); } /* 在HDC上绘制指定区域的画面 */ void sheet_refresh(HDC hdc, RECT rect) { HBITMAP hbmpMem = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top); HDC hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hbmpMem); HDC hdcBmp = CreateCompatibleDC(hdc); RECT rcDraw, rcSheet; int z; for (z = 0; z <= shtctl->top; z++) { rcSheet.left = shtctl->sheets[z]->x; rcSheet.top = shtctl->sheets[z]->y; rcSheet.right = rcSheet.left + shtctl->sheets[z]->width; rcSheet.bottom = rcSheet.top + shtctl->sheets[z]->height; if (!IntersectRect(&rcDraw, &rcSheet, &rect)) continue; RECT rcDrawMem = rcDraw; OffsetRect(&rcDrawMem, -rect.left, -rect.top); SelectObject(hdcBmp, shtctl->sheets[z]->hbmp); if (shtctl->sheets[z]->invisible_color == -1) BitBlt(hdcMem, rcDrawMem.left, rcDrawMem.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, hdcBmp, rcDraw.left - rcSheet.left, rcDraw.top - rcSheet.top, SRCCOPY); else TransparentBlt(hdcMem, rcDrawMem.left, rcDrawMem.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, hdcBmp, rcDraw.left - rcSheet.left, rcDraw.top - rcSheet.top, rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, shtctl->sheets[z]->invisible_color); } BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcMem, 0, 0, SRCCOPY); DeleteDC(hdcBmp); DeleteDC(hdcMem); DeleteObject(hbmpMem); } void sheet_refresh(int x0, int y0, int x1, int y1) { InvalidateRect(hWnd, &make_rect(x0, y0, x1, y1), FALSE); } void sheet_refresh(RECT rect) { InvalidateRect(hWnd, &rect, FALSE); } void sheet_refresh(SHEET *sht) { RECT rect; rect.left = sht->x; rect.top = sht->y; rect.right = sht->x + sht->width; rect.bottom = sht->y + sht->height; sheet_refresh(rect); } void sheet_refresh(SHEET *sht, RECT rect) { OffsetRect(&rect, sht->x, sht->y); sheet_refresh(rect); } void sheet_set_caret(SHEET *sht, int x, int y, COLORREF color, COLORREF bkColor) { sheet_set_caret(sht, x, y, CARET_DEF_WIDTH, CARET_DEF_HEIGHT, color, bkColor); } void sheet_set_caret(SHEET *sht, int x, int y, int width, int height, COLORREF color, COLORREF bkColor) { sht->caret.back_color = bkColor; sht->caret.color = color; sht->caret.rect.left = x; sht->caret.rect.top = y; sht->caret.rect.right = x + width; sht->caret.rect.bottom = y + height; } void sheet_setinfo(SHEET *sht, int width, int height, COLORREF invisible_color) { sht->width = width; sht->height = height; sht->invisible_color = invisible_color; } void sheet_setz(SHEET *sht, int z_index) { int z; int old = sht->z; if (z_index > shtctl->top + 1) z_index = shtctl->top + 1; if (z_index < -1) z_index = -1; sht->z = z_index; if (old > z_index) { if (z_index >= 0) { for (z = old; z > z_index; z--) { shtctl->sheets[z] = shtctl->sheets[z - 1]; shtctl->sheets[z]->z = z; } shtctl->sheets[z_index] = sht; } else { // hide if (shtctl->top > old) { for (z = old; z < shtctl->top; z++) { shtctl->sheets[z] = shtctl->sheets[z + 1]; shtctl->sheets[z]->z = z; } } shtctl->top--; } sheet_refresh(sht->x, sht->y, sht->x + sht->width, sht->y + sht->height); } else if (old < z_index) { if (old >= 0) { for (z = old; z < z_index; z++) { shtctl->sheets[z] = shtctl->sheets[z + 1]; shtctl->sheets[z]->z = z; } shtctl->sheets[z_index] = sht; } else { // display for (z = shtctl->top; z >= z_index; z--) { shtctl->sheets[z + 1] = shtctl->sheets[z]; shtctl->sheets[z + 1]->z = z + 1; } shtctl->sheets[z_index] = sht; shtctl->top++; } sheet_refresh(sht->x, sht->y, sht->x + sht->width, sht->y + sht->height); } } void shtctl_init(void) { RECT rect; GetClientRect(hWnd, &rect); shtctl_init(rect.right - rect.left, rect.bottom - rect.top); } void shtctl_init(int width, int height) { int i; shtctl = (SHTCTL *)memman_alloc_4k(sizeof(SHTCTL)); shtctl->width = width; shtctl->height = height; shtctl->top = -1; shtctl->active = shtctl->closing = NULL; shtctl->move_info.sht = NULL; for (i = 0; i < MAX_SHEETS; i++) shtctl->sheets0[i].flags = 0; }
|