Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Хронологический график средствами WinAPI

3.7K
24 февраля 2009 года
_lobster_
115 / / 10.04.2005
Привет всем!
Вообщем, стоит задача реализации графика на подобии графиков в диспетчере задач Windows. Подручными средствами пытался опеределить их принадлежность к common control-ам, ничего не получилось:(. Может кто сталкивался с такой задачей или кто-нить видел примерные решения ?
P.S. В С Builder и Delphi есть такая компонента как TPerformanceGraph, но проблема в том, что они собирают большие по размерам модули, так что их использование сразу отпадает!
87
24 февраля 2009 года
Kogrom
2.7K / / 02.02.2008
Наверно можно найти подходящий исходник. Я как-то делал подобное, правда, сразу для нескольких процессов. Но у меня оно не существует отдельно от приложения - надо выколупывать. Это может занять некоторое время. Плюс к тому и весить оно будет килобайт 300...
3.7K
24 февраля 2009 года
_lobster_
115 / / 10.04.2005
Цитата:
Наверно можно найти подходящий исходник.


Вот приглядываюсь к классу TPerformanceGraph, придется тогда немного помучиться, чтоб его заточить под GDI.

355
24 февраля 2009 года
<SCORP>
786 / / 21.10.2006
а в чём, собссно, проблема? график нарисовать - задача двольно тривиальная. из "фич" в диспетчере задач я заметил только автоматический выбро масштаба оптимального, что тоже сделать не сильно проблемно.
почему не написать что-то удовлетворяющее своим нужнам? вроде не накладно, с первого взгляда
3.7K
25 февраля 2009 года
0nni
326 / / 24.06.2008
Тебе на си или на паскале нужен?
3.7K
25 февраля 2009 года
_lobster_
115 / / 10.04.2005
Цитата: 0nni
Тебе на си или на паскале нужен?



Желательно на С, мона и на паскале :) переделаю, а есть что предложить ?

3.7K
25 февраля 2009 года
0nni
326 / / 24.06.2008
Вот целый класс, Графика конечно не ах, (да и комментариев нет), но минимум что надо
Код:
program Project1;

uses
  Windows,
  Messages;

const
  EXWNDLONG_SIZE = 4 *4;
  GWL_POINTS = 0;
  GWL_MIN = 4;
  GWL_MAX = 8;
  GWL_STEPSIZE = 12;

  GM_SETMINMAXVALUE = WM_USER;
  GM_ADDPOINT = WM_USER + 1;

type
  tPoints = array of Integer;
  pPoints = ^tPoints;

function WndProc(Wnd : HWND; msg : Cardinal; wParam, lParam : Integer) : Integer; stdcall;
var PaintStuct : TPaintStruct;
    i, len, y, Range, Min, Max : Integer;
    Scale : Double;
    Points : pPoints;
    rt : TRect;
begin
case msg of
                WM_CREATE :
                        begin
                          New(Points);
                          SetWindowLong(Wnd, GWL_POINTS, Integer(Points));

                          SetWindowLong(wnd, GWL_MIN, 0);
                          SetWindowLong(wnd, GWL_MAX, 64);
                          SetWindowLong(wnd, GWL_STEPSIZE, 8);
                          SetTimer(wnd, 0, 450, nil);
                        end; {WM_CREATE}
                WM_DESTROY :
                        begin
                          Points := pPoints( GetWindowLong(Wnd, GWL_POINTS) );
                          SetLength(Points^, 0);
                          Dispose(Points);
                          PostQuitMessage(0);
                        end; {WM_DESTOY}
                WM_PAINT :
                        begin
                                BeginPaint(Wnd, PaintStuct);
                                  FillRect(PaintStuct.hdc, PaintStuct.rcPaint, GetStockObject(WHITE_BRUSH));

                                  Points := pPoints( GetWindowLong(Wnd, GWL_POINTS) );
                                  GetClientRect(wnd, rt);
                                  Min := GetWindowLong(wnd, GWL_MIN);
                                  Max := GetWindowLong(wnd, GWL_MAX);
                                  Range := Abs(min) + abs(max);
                                  Scale := rt.Bottom / Range;

                                  y := trunc(rt.Bottom - Points^[0]*scale);
                                  y := trunc(y + Min*scale);
                                  MoveToEx(PaintStuct.hdc, rt.Right, y, nil);
                                  //нет смысла перересовывать все, можно расчитать PaintStuct.rcPaint
                                  for i := 1 to Length(Points^) - 1  do
                                  begin
                                    Dec(rt.Right, GetWindowLong(Wnd, GWL_STEPSIZE));
                                    y := trunc(rt.Bottom - Points^*scale);
                                    y := trunc(y + Min*scale);
                                    LineTo(PaintStuct.hdc, rt.Right, y);
                                  end;
                                  Writeln;
                                   
                                EndPaint(Wnd, PaintStuct);
                        end; {WM_PAINT}
                WM_TIMER :
                        begin
                          SendMessage(wnd, GM_ADDPOINT, Random(64), 0);// собственно нужно только это                          
                          //InvalidateRect(wnd, nil, false);
                        end; { WM_TIMER }
                WM_SIZE  :
                        begin
                          Points := pPoints( GetWindowLong(Wnd, GWL_POINTS) );
                          GetClientRect(wnd, rt);
                          SetLength(Points^, (rt.Right div  GetWindowLong(Wnd, GWL_STEPSIZE)) + 1);
                        end; { WM_SIZE }
                GM_ADDPOINT :
                        begin
                          Points := pPoints( GetWindowLong(Wnd, GWL_POINTS) );
                          for i :=  Length(Points^) - 1 downto  0 do Points^[i+1] := Points^;
                          //CopyMemory(@Points^[1], @Points^[0], Length(Points^) - 1);
                          Points^[0] := wParam;
                          i := GetWindowLong(wnd, GWL_STEPSIZE);
                          ScrollWindow(Wnd, -i, 0, nil, nil);
                        end { GM_ADDPOINT }
                else
                        begin
                          Result := DefWindowProc(Wnd, msg, wParam, lParam);
                        end;
        end
end;

var
  wnd : HWND;
  msg : TMsg;
  wc  : TWndClass;
begin
  ZeroMemory(@wc, SizeOf(wc));
  wc.style := CS_DBLCLKS or CS_OWNDC or CS_VREDRAW or CS_HREDRAW;
  wc.lpfnWndProc := @WndProc;
  wc.cbWndExtra := EXWNDLONG_SIZE;
  wc.hInstance := hInstance;
  wc.hIcon := LoadIcon(0, IDI_APPLICATION);
  wc.hCursor := LoadCursor(0, IDC_ARROW);
  wc.lpszClassName := 'GraphicWndClass';
  if not Boolean(RegisterClass(wc)) then
  begin
    MessageBox(0, PChar('Class <' + wc.lpszClassName + '> is not register'), nil, MB_ICONERROR or MB_SYSTEMMODAL);
    ExitProcess(0)
  end;

  wnd := CreateWindow('GraphicWndClass', 'Graphic', WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      0, 0, HInstance, nil);

  if wnd = 0 then
  begin
    MessageBox(0, PChar('Window not created'), nil, MB_ICONERROR or MB_SYSTEMMODAL);
    ExitProcess(0)
  end;

  ShowWindow(wnd, SW_SHOW);
  while GetMessage(msg, 0, 0, 0) do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
                       
end.

Меньше часа работы =)
3.7K
26 февраля 2009 года
0nni
326 / / 24.06.2008
Кстати fpc, выдает obj-файлы. если есть возможность их подключить то код можно и не переписывать (с массивом динамическим что делать будуте?). Есть еще вариант оформить класс в dll.
3.7K
26 февраля 2009 года
_lobster_
115 / / 10.04.2005
Ды нет, я все-таки перепишу на С, а с массивом что-нить придумаю :) что получится, выложу тут.
3.7K
26 февраля 2009 года
0nni
326 / / 24.06.2008
ок. Там только в коде WriteLn; лишний. Я для отладки все в консоль вывожу, вот и забыл убрать.
3.7K
27 февраля 2009 года
_lobster_
115 / / 10.04.2005
Вообщем, пока нет времени переписать все на Си:(
Для тех кто заинтересовался: в коде на паскале используется 32-разрядное значение в дополнительном пространстве памяти об окне для хранения информации для графика, можно использовать либо глобальные переменные, либо если это класс, защищенные переменые! Вместо паскалевского динамического массива использем вектор,а если проще, то просто буффер с DWORD значениями. При изменении размера окна просто делаем realloc памяти! Вообщем-то все! Как будет время выложу полный исходник класса.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог