Frodo_Torbins
Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Код: unit F_StatCtrlDib; interface uses Windows, Messages, F_Windows; procedure CreateVisualStatic(hWnd: HWND); procedure RemoveVisualStatic(hWnd: HWND); implementation const ID_TIMER = 101; MAX_WIDTH = 89; MAX_HEIGTH = 29; type TCtrlWndProc = function(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; TbmpBits = Array[1..MAX_HEIGTH, 1..MAX_WIDTH] of TRGBQuad; PbmpBits = ^TbmpBits; P_CTRL_PRO = ^T_CTRL_PRO; T_CTRL_PRO = packed record CtrlProc: TCtrlWndProc; // hdcMem : HDC; hbmMem : HBITMAP; hbmOld : HBITMAP; bmBits : PbmpBits; //Указатель на пиксели тоже храним end; var pcp: P_CTRL_PRO; // procedure DrawGridLines(pcp: P_CTRL_PRO); type TBits = Array of TRGBQuad; var lpBits: TBits; bmi : TBitmapInfo; pixel : Integer; procedure SetMemDCPixel(bits: TBits; X, Y: Integer); begin bits[Y*MAX_WIDTH+ X].rgbBlue := 0; bits[Y*MAX_WIDTH+ X].rgbGreen := 255; bits[Y*MAX_WIDTH+ X].rgbRed := 0; bits[Y*MAX_WIDTH+ X].rgbReserved := 0; end; begin // { with bmi.bmiHeader do begin biSize := SizeOf(bmi.bmiHeader); biWidth := MAX_WIDTH; biHeight := -MAX_HEIGTH; biPlanes := 1; biBitCount := 32; biCompression := BI_RGB; end; SetLength(lpBits, MAX_HEIGTH * MAX_WIDTH); GetDIBits(pcp.hdcMem, pcp.hbmMem, 0, MAX_HEIGTH, @lpBits[0], bmi, DIB_RGB_COLORS); // left. SetMemDCPixel(lpBits, 0, 0); SetMemDCPixel(lpBits, 1, 0); SetMemDCPixel(lpBits, 1, 10); SetMemDCPixel(lpBits, 0, 12); SetMemDCPixel(lpBits, 1, 12); SetMemDCPixel(lpBits, 1, 14); SetMemDCPixel(lpBits, 0, 24); SetMemDCPixel(lpBits, 1, 24); for pixel := 0 to (MAX_HEIGTH - 3) do if not Odd(pixel) then SetMemDCPixel(lpBits, 2, pixel); // right. for pixel := 0 to (MAX_HEIGTH - 3) do if not Odd(pixel) then SetMemDCPixel(lpBits, MAX_WIDTH - 3, pixel); SetMemDCPixel(lpBits, MAX_WIDTH - 1, 0); SetMemDCPixel(lpBits, MAX_WIDTH - 2, 0); SetMemDCPixel(lpBits, MAX_WIDTH - 2, 10); SetMemDCPixel(lpBits, MAX_WIDTH - 1, 12); SetMemDCPixel(lpBits, MAX_WIDTH - 2, 12); SetMemDCPixel(lpBits, MAX_WIDTH - 2, 14); SetMemDCPixel(lpBits, MAX_WIDTH - 1, 24); SetMemDCPixel(lpBits, MAX_WIDTH - 2, 24); // bottom. for pixel := 2 to (MAX_WIDTH - 3) do if not Odd(pixel) then SetMemDCPixel(lpBits, pixel, MAX_HEIGTH - 3); SetMemDCPixel(lpBits, 10, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 10, MAX_HEIGTH - 1); SetMemDCPixel(lpBits, 18, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 26, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 34, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 44, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 44, MAX_HEIGTH - 1); SetMemDCPixel(lpBits, 54, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 62, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 70, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 78, MAX_HEIGTH - 2); SetMemDCPixel(lpBits, 78, MAX_HEIGTH - 1); // SetDIBits(pcp.hdcMem, pcp.hbmMem, 0, MAX_HEIGTH, @lpBits[0], bmi, DIB_RGB_COLORS); } pcp.bmBits^[2, 2].rgbGreen:=255; pcp.bmBits^[6, 2].rgbGreen:=255; pcp.bmBits^[7, 6].rgbGreen:=255; pcp.bmBits^[6, 7].rgbGreen:=255; pcp.bmBits^[5, 7].rgbGreen:=255; pcp.bmBits^[4, 7].rgbGreen:=255; pcp.bmBits^[3, 7].rgbGreen:=255; pcp.bmBits^[2, 7].rgbGreen:=255; pcp.bmBits^[1, 6].rgbGreen:=255; end; // function CtrlWndProc_WmPaint(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var ps: TPaintStruct; begin // BeginPaint(hWnd, ps); // StretchBlt(ps.hdc, ps.rcPaint.Left, ps.rcPaint.Top, ps.rcPaint.Right, ps.rcPaint.Bottom, pcp.hdcMem, 0, 0, MAX_WIDTH, MAX_HEIGTH, SRCCOPY); //DPI Aware // EndPaint(hWnd, ps); // Result := 0; end; // function CtrlWndProc_WmTimer(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; var dwStyle: DWORD; begin // //Зачем тут это? // CallWindowProcW(@pcp.CtrlProc, hWnd, WM_PRINTCLIENT, pcp.hdcMem, PRF_CLIENT); // //Достаточно вызвать один раз, после создания битмапа т к содержимое все равно не меняется DrawGridLines(pcp); // dwStyle := RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE; RedrawWindow(hWnd, nil, 0, dwStyle); // Result := 0; end; // function CtrlWndProc_WmEraseBkgnd(pcp: P_CTRL_PRO; hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; begin // Result := 1; end; // function StatWndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin pcp := P_CTRL_PRO(GetWindowLongW(hWnd, GWL_USERDATA)); if (pcp = nil) then begin Result := DefWindowProcW(hWnd, uMsg, wParam, lParam); Exit; end; case uMsg of // WM_DESTROY: begin RemoveVisualStatic(hWnd); end; // WM_PRINTCLIENT, WM_PAINT, WM_UPDATEUISTATE: begin Result := CtrlWndProc_WmPaint(pcp, hWnd, uMsg, wParam, lParam); end; // WM_TIMER: begin Result := CtrlWndProc_WmTimer(pcp, hWnd, uMsg, wParam, lParam); end; // WM_ERASEBKGND: begin Result := CtrlWndProc_WmEraseBkgnd(pcp, hWnd, uMsg, wParam, lParam); end; else Result := CallWindowProcW(@pcp.CtrlProc, hWnd, uMsg, wParam, lParam); end; end; // procedure CreateVisualStatic(hWnd: HWND); var hdcIn : HDC; dwStyle: DWORD; bmi : TBitmapInfo; begin RemoveVisualStatic(hWnd); pcp := P_CTRL_PRO(HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, SizeOf(T_CTRL_PRO))); ZeroMemory(pcp, SizeOf(T_CTRL_PRO)); pcp.CtrlProc := TCtrlWndProc(Pointer(GetWindowLongW(hWnd, GWL_WNDPROC))); with bmi.bmiHeader do begin biSize := SizeOf(bmi.bmiHeader); biWidth := MAX_WIDTH; biHeight := -MAX_HEIGTH; //Изменили порядок строк biPlanes := 1; biBitCount := 32; biCompression := BI_RGB; end; hdcIn := GetDC(hWnd); pcp.hdcMem := CreateCompatibleDC(hdcIn); //Указатель нам еще понадобится при рисовании pcp.hbmMem := CreateDIBSection(hdcIn, bmi, DIB_RGB_COLORS, Pointer(pcp.bmBits), 0, 0); pcp.hbmOld := SelectObject(pcp.hdcMem, pcp.hbmMem); ReleaseDC(hWnd, hdcIn); dwStyle := SWP_NOMOVE or SWP_NOZORDER; dwStyle := SWP_NOSIZE or dwStyle; //DPI Aware SetWindowPos(hWnd, HWND_TOP, 0, 0, MAX_WIDTH, MAX_HEIGTH, dwStyle); SetWindowLongW(hWnd, GWL_USERDATA, Longint(pcp)); SetWindowLongW(hWnd, GWL_WNDPROC, Longint(@StatWndProc)); SendmessageW(hWnd, WM_TIMER, 0, 0); SetTimer(hWnd, ID_TIMER, 25, nil); end; // procedure RemoveVisualStatic(hWnd: HWND); var dwStyle: DWORD; begin pcp := P_CTRL_PRO(GetWindowLongW(hWnd, GWL_USERDATA)); if (pcp <> nil) then begin // if (pcp.hdcMem <> 0) then begin SelectObject(pcp.hdcMem, pcp.hbmOld); DeleteObject(pcp.hbmMem); DeleteDC(pcp.hdcMem); end; // KillTimer(hWnd, ID_TIMER); // SetWindowLongW(hWnd, GWL_WNDPROC, Longint(@pcp.CtrlProc)); // SetWindowLongW(hWnd, GWL_USERDATA, 0); HeapFree(GetProcessHeap, 0, pcp); // dwStyle := RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE; RedrawWindow(hWnd, nil, 0, dwStyle); end; end; end. |
|