Конференция "Прочее" » Обновил MSGLoger.exe
 
  • koha! (13.12.08 13:36) [0]
    Если кому интересно...
    - Расширил значительно функциональность программы, добавил множество опций ....
    хочу знать ваше мнение, на сколько получилась хорошая прога.  

    Добавлены новые процедуры в модуль MSGLog.pas

    SendDebugMsgWnd(WndCaption: String; DebugMsg: String);
    В этой процедуре добавлен параметр "WndCaption", если запущено несколько окон программы MSGLoger.exe с разными заголовками окна, например, одно окно имеет заголовок "MSGLoger", а другое "LogView", то каждому  окну можно послать отдельное сообщение, для этого необходимо вызвать процедуры в следующем порядке SendDebugMsgWnd('MSGLoger','Сообщение программе с первым заголовком')  и SendDebugMsgWnd('LogView','Сообщение программме с  заголовком два').

    SendDebugMsgLastError(DebugMsg: String; LastError: Integer);
    В этой процедуре реализована возможность передать код ошибки "GetLastError", например, вы не собираетесь обрабатывать и поднимать сообщение об ошибке через  "RaiseLastOSError" или "RaiseLastWin32Error", или RaiseLastOSError(GetLastError) в сомой программе, то можно код ошибки отправить через процедуру SendDebugMsgLastError(), а "MSGLoger.exe" этот код преобразует текстовое сообщение как и "RaiseLastOSError" и отразит в очете.
    Например:
    try
    // Выполняемый код ...
    ecxept
       SendDebugMsgLastError('Ошибка в модуле Unit1 ...', GetLastError);
      // Вызываем вместо RaiseLastOSError;
     exit;
    end;



    SendDebugMsgWndLastError(WndCaption, DebugMsg: String; LastError: Integer);
    Это процедура имеет такие свойства, как и предыдущие, она может отправлять сообщения в разные окна программы MSGLoger.exe и передавать код ошибки.
  • koha! (13.12.08 14:19) [1]
    Адресочек для файла, то забыл...
    Для скачивания:
    www.elsetrue.narod.ru/Softfolder/msgloger_lastver.rar
  • koha! (13.12.08 14:20) [2]
    Удалено модератором
  • Loginov Dmitry © (13.12.08 14:44) [3]
    > хочу знать ваше мнение, на сколько получилась хорошая прога.
    >  


    Довольно симпатичная. При запуске негативных эмоций не вызывает.

    По сути: часто приходится разрабатывать многопоточные приложения,
    единственный надежным способом их отладки является запись в лог (в
    дебаггере отладить получается через раз, IDE (и винда) виснет
    постоянно). В таких случаях помимо ID процесса в лог полезно выводить
    ID потока. Было бы лучше, если бы такой вариант в модуле "MsgLog.pas"
    учитывался.

    Еще пожелание. Назначение сообщений может быть разным. Это может быть
    критическая ошибка, некритическая ошибка, предупреждения, какое-либо
    событие, информационное сообщение, отладочное сообщение и т.д. Было бы
    хорошо, если бы программа учитывала тип сообщения, и подсвечивала их
    разным (лучше-настраиваемым) цветом.

    Еще нашел интересную настройку:
    "Стартовать при старте в трэй"
  • koha! (13.12.08 15:10) [4]
    Сорри.... для всех кто уже скачал, там была маленькая ошибочка в модуле MsgLog.pas
    Только что исправил и заменил архив...
    что бы не качать снова, вот исправленный модуль:

    {************************************************************************* *****}
    { Module MSGLog.pas v1.1  for MSGLoger.exe                                     }  
    { elsstrue - software  http://www.elsetrue.narod.ru/msgloger.htm               }
    {******************************************************************************}

    Unit MsgLog;

    interface

    Type

     DWORD   = LongWord;
     HWND    = type LongWord;
     UINT    = LongWord;
     WPARAM  = Longint;
     LPARAM  = Longint;
     LRESULT = Longint;

     { lParam of WM_COPYDATA message points to... }
     PCopyDataStruct = ^TCopyDataStruct;
     tagCOPYDATASTRUCT = packed record
       dwData: DWORD;
       cbData: DWORD;
       lpData: Pointer;
     end;
     TCopyDataStruct = tagCOPYDATASTRUCT;
     COPYDATASTRUCT  = tagCOPYDATASTRUCT;

    const
     WndClass  = 'TMSGLoger';
     kernel32  = 'kernel32.dll';
     user32    = 'user32.dll';
     WM_USER      = $0400;
     WM_COPYDATA  = $004A;

    function FindWindow(lpClassName, lpWindowName: PChar): HWND; stdcall; external user32 name 'FindWindowA';
    function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; external user32 name 'SendMessageA';
    function GetCurrentProcessId: DWORD; stdcall; external kernel32 name 'GetCurrentProcessId';
    procedure OutputDebugString(lpOutputString: PChar); stdcall; external kernel32 name 'OutputDebugStringA';
    function StrLen(const Str: PChar): Cardinal;
    procedure SendDebugMsg(DebugMsg: String);

    // SendDebugMsgWnd - функция для новой версии MSGLoger v. 1.0.1.12 и выше
    // Реализована возможность посылать сообщения для разных окон,
    // для этого в MSGLoger нужно в настройках изменить заголовок окна.
    // нужное окно будет найдено по заголовку.....
    procedure SendDebugMsgWnd(WndCaption: String; DebugMsg: String);

    // В этих функциях добавлена возможность передовать не только
    // текстовые соодщения, но и код ошибки GetLastError
    // MSGloger по умолчанию не обрабатывает ошибки равные 0,
    // если LastError не равняется 0, то

    procedure SendDebugMsgLastError(DebugMsg: String; LastError: Integer);
    procedure SendDebugMsgWndLastError(WndCaption, DebugMsg: String; LastError: Integer);

    implementation

    {----------------------- StrLen() From SysUtils -------------------------------}
    function StrLen(const Str: PChar): Cardinal; assembler;
    asm
           MOV     EDX,EDI
           MOV     EDI,EAX
           MOV     ECX,0FFFFFFFFH
           XOR     AL,AL
           REPNE   SCASB
           MOV     EAX,0FFFFFFFEH
           SUB     EAX,ECX
           MOV     EDI,EDX
    end;

    {---------------------------- SendDebugMsg ------------------------------------}
    procedure SendDebugMsg(DebugMsg: String);
    var
     WND      : HWND;
     CopyData : TCopyDataStruct;
    begin
     OutputDebugString(PChar(DebugMsg));
     WND:=FindWindow(PChar(WndClass),Nil); //Find window on Class
     if WND <> 0 then begin
       With CopyData do begin
         dwData := 0;
         cbData := StrLen(PChar(DebugMsg));
         lpData := PChar(DebugMsg);
       end;
       SendMessage(WND,WM_COPYDATA,GetCurrentProcessId,Integer(@CopyData));
     end;
    end;
    {-------------------------- SendDebugMsgWnd -----------------------------------}
    procedure SendDebugMsgWnd(WndCaption: String; DebugMsg: String);
    var
     WND      : HWND;
     CopyData : TCopyDataStruct;
    begin
     OutputDebugString(PChar(DebugMsg));
     WND:=FindWindow(Nil,PChar(WndCaption)); //Find window on Caption
     if WND <> 0 then begin
       With CopyData do begin
         dwData := 0;
         cbData := StrLen(PChar(DebugMsg));
         lpData := PChar(DebugMsg);
       end;
       SendMessage(WND,WM_COPYDATA,GetCurrentProcessId,Integer(@CopyData));
     end;
    end;
    {------------------------ SendDebugMsgLastError -------------------------------}
    procedure SendDebugMsgLastError(DebugMsg: String; LastError: Integer);
    var
     WND      : HWND;
     CopyData : TCopyDataStruct;
    begin
     OutputDebugString(PChar(DebugMsg));
     WND:=FindWindow(PChar(WndClass),Nil); //Find window on Class
     if WND <> 0 then begin
       With CopyData do begin
         dwData := LastError;
         cbData := StrLen(PChar(DebugMsg));
         lpData := PChar(DebugMsg);
       end;
       SendMessage(WND,WM_COPYDATA,GetCurrentProcessId,Integer(@CopyData));
     end;
    end;
    {-------------------------- SendDebugMsgWndLastError --------------------------}
    procedure SendDebugMsgWndLastError(WndCaption, DebugMsg: String; LastError: Integer);
    var
     WND      : HWND;
     CopyData : TCopyDataStruct;
    begin
     OutputDebugString(PChar(DebugMsg));
     WND:=FindWindow(Nil,PChar(WndCaption)); //Find window on Caption
     if WND <> 0 then begin
       With CopyData do begin
         dwData := LastError;
         cbData := StrLen(PChar(DebugMsg));
         lpData := PChar(DebugMsg);
       end;
       SendMessage(WND,WM_COPYDATA,GetCurrentProcessId,Integer(@CopyData));
     end;
    end;

    end.

  • koha! (13.12.08 15:20) [5]

    > Loginov Dmitry ©   (13.12.08 14:44) [3]


    > помимо ID процесса в лог полезно выводитьID потока. Было
    > бы лучше, если бы такой вариант в модуле "MsgLog.pas"учитывался.
    >

    - Учту ..


    > Было быхорошо, если бы программа учитывала тип сообщения,
    >  и подсвечивала ихразным (лучше-настраиваемым) цветом.


    - Да вот именно так я и собирался сделать, наверное в следующей версии....
    А кто тип должен указывать? программист при вызове отладочной функции или программа должна сама анализировать по коду GetLastError?

    - еще в плане сделать ее сетевой: клиен-сервер дабы на удаленных просматривать код, как бы настройки уже есть, пока скрыты, но еще не реализован сам клиент-скервер.
  • koha! (13.12.08 15:30) [6]
    В каждой процедуре модуля MsgLog.pas вызывается еще одна дополнительная функция OutputDebugString, которая отправляет сообшения в другую утилиту "Dbgview.exe" от "Sysinternals.exe" www.sysinternals.com
  • Loginov Dmitry © (13.12.08 15:54) [7]
    > А кто тип должен указывать? программист при вызове отладочной
    > функции или программа должна сама анализировать по коду
    > GetLastError?


    Программист
  • koha! (13.12.08 16:11) [8]
    Еще одну фишечку хочу показать..
    - это прозрачность...  
    - для чего было сделано?
    вот картинки и все станет понятно....

    http://webfile.ru/2473141
    http://webfile.ru/2473151

    ... слишком не хотелось портить внешний вид второго "десктопа".
  • koha! (13.12.08 16:53) [9]

    > Loginov Dmitry ©   (13.12.08 14:44) [3]

    > помимо ID процесса в лог полезно выводитьID потока.

    В самом деле стало интересно, а как можно узнать ID потока в котором выполнятеся функция? Или узнать хотябы узнать в каком потоке произшло исключение?
  • DVM © (13.12.08 17:46) [10]

    > а как можно узнать ID потока в котором выполнятеся функция?

    ВзятьТекущийПотокаИД()
  • koha! (13.12.08 18:03) [11]

    > DVM ©   (13.12.08 17:46) [10]
    > > а как можно узнать ID потока в котором выполнятеся функция?
    > ВзятьТекущийПотокаИД()


    имеется ввиду эта функция GetCurrentProcessId?
  • koha! (13.12.08 18:08) [12]
    я протупил... да вот же она "GetCurrentThreadId"
  • koha! (13.12.08 18:08) [13]
    Удалено модератором
 
Конференция "Прочее" » Обновил MSGLoger.exe
Есть новые Нет новых   [134447   +40][b:0][p:0.004]