V1s1ter Спасибо, но там VCL, пробовал код подставлять для своих нужд, чего-то не получилось.
ShIvADeSt Так, посмотрел, вроде какая-то фигня получилась. Только есть один вопрос. Как развернуть HDC по горизонтали. Всякая фигня попадается в интернете, а толку ноль.
[more=Дальше]unit F_GridStat;
interface
uses
Windows, Messages;
const
SG_SETBKGNDCOLOR = WM_USER + 101; // цвет фона графика
SG_SETGRIDCOLOR = WM_USER + 102; // цвет сетки графика
SG_SETLINECOLOR = WM_USER + 103; // цвет линий графика
SG_SETSIZETHICKX = WM_USER + 104; // шаг сетки по горизонтали
SG_SETSIZETHICKY = WM_USER + 105; // шаг сетки по вертикали
SG_SETNEWGRIDLINE = WM_USER + 106; // добавление новой координаты
SG_CLEARGRIDLINE = WM_USER + 107; // очистка сетки
procedure CreateStaticGridW(hWnd: Thandle);
procedure RemoveStaticGridW(hWnd: Thandle);
implementation
const
StatGridProp = 'UxGridPrtSublassInfo';
type
TMainWndProc = function(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
P_GRID_PRO = ^T_GRID_PRO;
T_GRID_PRO = packed record
WndProc : TMainWndProc;
clrBkgnd: TColorRef;
clrGrid : TColorRef;
clrLine : TColorRef;
sThickX : Byte;
sThickY : Byte;
Points : Array of TPoint;
maxLines: Integer;
end;
var
pgp: P_GRID_PRO;
//
procedure LineEx(hdc: HDC; x1, y1, x2, y2: Integer);
begin
MoveToEx(hdc, x1, y1, nil);
LineTo(hdc, x2, y2);
end;
//
procedure PolylineEx(hdc: HDC; Points: Array of TPoint);
var
I: Integer;
begin
for I := 1 to High(Points) do
LineEx(hdc, Points[I - 1].x, Points[I - 1].y, Points[I].x, Points[I].y);
end;
//
procedure DrawGridEx(hdc: HDC; hWnd: HWND; pgp: P_GRID_PRO);
var
rc : TRect;
iWidth : Integer;
iHeight: Integer;
begin
GetClientRect(hWnd, rc);
iWidth := rc.Right - rc.Left;
iHeight := rc.Bottom - rc.Top;
for iHeight := 0 to iHeight do
for iWidth := 0 to iWidth do
if (not ((iHeight mod pgp^.sThickY) <> 0)) or (not ((iWidth mod pgp^.sThickX) <> 0)) then
SetPixel(hdc, iWidth, iHeight, pgp^.clrGrid);
end;
//
function GridWndProc_OnWmPaint(hWnd: HWND; pgp: P_GRID_PRO): LRESULT;
var
rc : TRect;
ps : TPaintStruct;
hbmNew: HBITMAP;
hbmOld: HBITMAP;
cdc : HDC;
PenNew: HPEN;
PenOld: HPEN;
nBrush: HBRUSH;
begin
GetClientRect(hWnd, rc);
BeginPaint(hWnd, ps);
cdc := CreateCompatibleDC(ps.hdc);
hbmNew := CreateCompatibleBitmap(ps.hdc, rc.Right - rc.Left, rc.Bottom - rc.Top);
hbmOld := SelectObject(cdc, hbmNew);
nBrush := CreateSolidBrush(pgp^.clrBkgnd);
FillRect(cdc, rc, nBrush); // FrameRect
PenNew := CreatePen(PS_SOLID, 1, pgp^.clrLine);
PenOld := SelectObject(cdc, PenNew);
DrawGridEx(cdc, hWnd, pgp);
PolylineEx(cdc, pgp^.Points);
DeleteObject(nBrush);
BitBlt(ps.hdc, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, cdc, 0, 0, SRCCOPY);
SelectObject(cdc, PenOld);
DeleteObject(PenNew);
SelectObject(cdc, hbmOld);
DeleteObject(hbmNew);
DeleteDC(cdc);
EndPaint(hWnd, ps);
//
Result := 0;
end;
//
function GridWndProc_OnSgSetBkgndColor(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.clrBkgnd := TColorRef(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgSetGridColor(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.clrGrid := TColorRef(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgSetLineColor(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.clrLine := TColorRef(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgSetSizeThickX(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.sThickX := Byte(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgSetSizeThickY(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.sThickY := Byte(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgSetNewGridLine(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
Inc(pgp^.maxLines);
SetLength(pgp^.Points, pgp^.maxLines);
pgp^.Points[pgp^.MaxLines - 1].X := LoWord(lParam);
pgp^.Points[pgp^.MaxLines - 1].Y := HiWord(lParam);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GridWndProc_OnSgClearGridLine(hWnd: HWND; pgp: P_GRID_PRO; lParam: LPARAM): LRESULT;
begin
pgp^.maxLines := 0;
SetLength(pgp^.Points, pgp^.maxLines);
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
Result := 0;
end;
//
function GripWndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
pgp := P_GRID_PRO(GetPropW(hWnd, StatGridProp));
if (pgp = nil) then
begin
Result := DefWindowProcW(hWnd, uMsg, wParam, lParam);
Exit;
end;
case uMsg of
//
WM_DESTROY:
begin
RemoveStaticGridW(hWnd);
end;
//
WM_PRINTCLIENT, WM_PAINT:
begin
Result := GridWndProc_OnWmPaint(hWnd, pgp);
end;
//
SG_SETBKGNDCOLOR:
begin
Result := GridWndProc_OnSgSetBkgndColor(hWnd, pgp, lParam);
end;
//
SG_SETGRIDCOLOR:
begin
Result := GridWndProc_OnSgSetGridColor(hWnd, pgp, lParam);
end;
//
SG_SETLINECOLOR:
begin
Result := GridWndProc_OnSgSetLineColor(hWnd, pgp, lParam);
end;
//
SG_SETSIZETHICKX:
begin
Result := GridWndProc_OnSgSetSizeThickX(hWnd, pgp, lParam);
end;
//
SG_SETSIZETHICKY:
begin
Result := GridWndProc_OnSgSetSizeThickY(hWnd, pgp, lParam);
end;
//
SG_SETNEWGRIDLINE:
begin
Result := GridWndProc_OnSgSetNewGridLine(hWnd, pgp, lParam);
end;
//
SG_CLEARGRIDLINE:
begin
Result := GridWndProc_OnSgClearGridLine(hWnd, pgp, lParam);
end;
else
Result := CallWindowProcW(@pgp^.WndProc, hWnd, uMsg, wParam, lParam);
end;
end;
//
procedure CreateStaticGridW(hWnd: Thandle);
begin
RemoveStaticGridW(hWnd);
New(pgp);
ZeroMemory(pgp, SizeOf(pgp));
pgp^.WndProc := TMainWndProc(Pointer(GetWindowLongW(hWnd, GWL_WNDPROC)));
pgp^.clrBkgnd := RGB(0, 0, 0);
pgp^.clrGrid := RGB(0, 128, 64);
pgp^.clrLine := RGB(255, 255, 0);
pgp^.sThickX := 11;
pgp^.sThickY := 11;
pgp^.maxLines := 0;
SetLength(pgp^.Points, pgp^.maxLines);
SetPropW(hWnd, StatGridProp, Cardinal(pgp));
SetWindowLongW(hWnd, GWL_WNDPROC, Longint(@GripWndProc));
RedrawWindow(hWnd, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE);
end;
//
procedure RemoveStaticGridW(hWnd: Thandle);
begin
pgp := P_GRID_PRO(GetPropW(hWnd, StatGridProp));
if (pgp <> nil) then
begin
RemovePropW(hWnd, StatGridProp);
SetWindowLongW(hWnd, GWL_WNDPROC, Longint(@pgp^.WndProc));
Dispose(pgp);
end;
end;
end.[/more]
[more=Инициализация] CreateStaticGridW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETBKGNDCOLOR, 0, RGB(0, 0, 0));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETGRIDCOLOR, 0, RGB(0, 128, 64));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETLINECOLOR, 0, RGB(255, 255, 0));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETSIZETHICKX, 0, 11);
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETSIZETHICKY, 0, 11);
//
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETNEWGRIDLINE, 0, MakeLong(0, 0));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETNEWGRIDLINE, 0, MakeLong(35, 12));
SendMessageW(GetDlgItem(hWnd, IDC_STATIC_GRAPHIC), SG_SETNEWGRIDLINE, 0, MakeLong(45, 42));
[/more]
Вобщем кому интересна сама идея. Я та кпонял что нужно создать переменную в которой требуется хранить число точек и по ней ориентироваться при отрисовке линий. Также хочется при каждом добавлении линии на контрол прокручивать всю отрисовку влево - ну как везде вот это все организовано впринципе для удобности и наглядности, ну или хотя бы подскажиет кто знает какими функциями это сделать. Просто пока таймер не добавил себе на диалог, посему не знаю как вообще управлять таким контролом.