Recent

Author Topic: Close CHM window created by TProcess  (Read 5276 times)

Gary Randall

  • Jr. Member
  • **
  • Posts: 70
Close CHM window created by TProcess
« on: January 23, 2015, 06:38:41 pm »
I have successfully implemented an existing CHM help file using a TProcess procedure to run hh.exe under Windows.  I can display and print any help topic in the CHM file.  I call help using the F1 key, a menu selection, or a Help button.  The Help buttons are placed on modal forms.  Once a CHM is opened it is only closed by clicking the "X" icon on the window.

I chose this method because lhelp doesn't display my CHM file correctly and there is no print function.  My CHM file was created using HelpScribble (http://www.helpscribble.com/) which I've used for a few years and really like.  lhelp adds extra lines between paragraphs, doesn't handle images, won't print, and I can't figure out how to display topics.

I would like to close the CHM windows when their creating forms are closed.  I assume I need to get a system handle to the window and use a system close, but can't find documentation on doing so.  Any suggestions will be appreciated.

While TProcess is a great solution for displaying CHM files under Windows,  I need cross-platform capability.  Are there corresponding system programs like hh.exe to do the same thing under Linux and Apple?  Are the shortcomings in lhelp being addressed?  I would prefer to use it when they are.

Thank you, Gary
« Last Edit: January 23, 2015, 10:02:16 pm by Gary Randall »
Windows 7 Home Premium 64 bit - SP 1
Lazarus Version #: 1.8.0; FPC Version: 3.0.4
SVN Revision 56594
i386-win32-win32/win64

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Close CHM window created by TProcess
« Reply #1 on: January 24, 2015, 05:30:08 am »
Are there corresponding system programs like hh.exe to do the same thing under Linux and Apple?
No, despite Linux has a bunch of CHM reader programs, none of them are considered standard. Even OS X doesn't know it at all, AFAIK. I guess the reason why lhelp was born is this, plus the ease of maintenance because the team doesn't have to worry about 3rd party changes.
Are the shortcomings in lhelp being addressed?
Have you reported?

Gary Randall

  • Jr. Member
  • **
  • Posts: 70
Re: Close CHM window created by TProcess
« Reply #2 on: January 24, 2015, 06:17:22 am »
Thank you, Leledumbo.  I didn't document my lhelp findings so I will put together a test program and do so.  I'm surprised there isn't more interest in CHM help files since they are so easy to create using an editor like HelpScribble.  What has been implemented in lhelp looks good.  From what you said it looks like the only cross-platform solution.

Gary
Windows 7 Home Premium 64 bit - SP 1
Lazarus Version #: 1.8.0; FPC Version: 3.0.4
SVN Revision 56594
i386-win32-win32/win64

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4468
  • I like bugs.
Re: Close CHM window created by TProcess
« Reply #3 on: January 24, 2015, 10:36:22 am »
I didn't document my lhelp findings so I will put together a test program and do so.  I'm surprised there isn't more interest in CHM help files since they are so easy to create using an editor like HelpScribble.

There are some bug reports, search for "lhelp".
Nobody is very actively developing it now but you could make it your pet project and improve it. For rendering it uses TurboPowerIPro which is buggy.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: Close CHM window created by TProcess
« Reply #4 on: January 24, 2015, 04:52:35 pm »
Note that you don't need hh.exe, see the examples in packages/winunits-base/tests  (hhex*)

Gary Randall

  • Jr. Member
  • **
  • Posts: 70
Re: Close CHM window created by TProcess
« Reply #5 on: January 25, 2015, 06:27:35 pm »
Thanks all,

I reviewed the bug status of lhelp and I see no activity in two - three years.  Although lhelp looks like the best solution this newbie isn't ready to tackle a project like that.  Perhaps in a few months I will be ready.  In the meantime maybe somebody can recommend CHM viewers for platforms other than Windows that will run under TProcess.

I may be missing something, but I didn't see anything encouraging in the winunits-base references I found.

I would still like to find a way to close a Windows TProcess instance from my program.  The TProcess.Options don't offer anything. 

Gary
Windows 7 Home Premium 64 bit - SP 1
Lazarus Version #: 1.8.0; FPC Version: 3.0.4
SVN Revision 56594
i386-win32-win32/win64

minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: Close CHM window created by TProcess
« Reply #6 on: January 25, 2015, 07:02:58 pm »
Hi Gary,
Here is a unit that works for me in Windows and Linux (sorry, no Apple code) to test if an process is running and if so, kill it. (ignore the GetUsername code)

HTH

Code: [Select]
unit uappisrunning;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils,FileUtil
  {$IFDEF WINDOWS}, Windows, JwaTlHelp32{$ENDIF}
  {$IFDEF LINUX},process{$ENDIF};
// JwaTlHelp32 is in fpc\packages\winunits-jedi\src\jwatlhelp32.pas

// Returns TRUE if EXEName is running under Windows or Linux
// Don't pass an .exe extension to Linux!
function AppIsRunning(const ExeName: string):Boolean;
procedure KillApp(const ExeName: string);
Function GetUserName:String;

implementation
// These functions return Zero if app is NOT running
// Override them if you have a better implementation
{$IFDEF WINDOWS}

function WindowsGetUserName: string;
var
  nsize: DWORD;
  sz: ansistring;
begin
  Result := 'unknown';
  nsize := 255;
  SetLength(sz, nsize);
  windows.GetUsername(PChar(sz), nsize);
  SetLength(sz, nsize);
  Result := Trim(sz);
end;

function WindowsAppIsRunning(const ExeName: string): integer;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := 0;
  while integer(ContinueLoop) <> 0 do
    begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeName))) then
      begin
      Inc(Result);
      end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
  CloseHandle(FSnapshotHandle);
end;
Procedure KillWindowsApp(const ExeName:String);
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  AHandle: THandle;
  ID: dword;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  while integer(ContinueLoop) <> 0 do
    begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeName))) then
      begin
             ID:=FProcessEntry32.th32ProcessID;
             AHandle := OpenProcess(PROCESS_ALL_ACCESS,False,ID); //uses windows
             TerminateProcess(AHandle,255);
      end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
  CloseHandle(FSnapshotHandle);
end;
{$ENDIF}
{$IFDEF LINUX}
function LinuxGetUserName: string;
begin
  Result:=GetEnvironmentVariableUTF8('USER');
end;
function LinuxAppIsRunning(const ExeName: string): integer;
var
  t: TProcess;
  s: TStringList;
begin
  Result := 0;
  t := tprocess.Create(nil);
  t.CommandLine := 'ps -C ' + ExeName;
  t.Options := [poUsePipes, poWaitonexit];
    try
    t.Execute;
    s := TStringList.Create;
      try
      s.LoadFromStream(t.Output);
      Result := Pos(ExeName, s.Text);
      finally
      s.Free;
      end;
    finally
    t.Free;
    end;
end;
procedure KillLinuxApp(const ExeName: string);
// killall -9 processname
// or pidof EXEName gives PID then kill PID
var
  t: TProcess;
  s: TStringList;
begin
  t := tprocess.Create(nil);
  t.CommandLine := 'killall -9 ' + ExeName;
  t.Options := [poUsePipes, poWaitonexit];
    try
    t.Execute;
    {
    s := TStringList.Create;
      try
      s.LoadFromStream(t.Output);
      Result := Pos(ExeName, s.Text);
      finally
      s.Free;
      end;
    }
    finally
    t.Free;
    end;
end;
{$ENDIF}
Function GetUserName:String;
begin
{$IFDEF WINDOWS}
        Result:=WindowsGetUserName;
{$ENDIF}
{$IFDEF LINUX}
Result:=LinuxGetUserName;
{$ENDIF}
end;

procedure KillApp(const ExeName: string);
begin
{$IFDEF WINDOWS}
  KillWindowsApp(ExeName);
{$ENDIF}
{$IFDEF LINUX}
  KillLinuxApp(ExeName);
{$ENDIF}
end;

function AppIsRunning(const ExeName: string):Boolean;
begin
{$IFDEF WINDOWS}
  Result:=(WindowsAppIsRunning(ExeName) > 0);
{$ENDIF}
{$IFDEF LINUX}
  Result:=(LinuxAppIsRunning(ExeName) > 0);
{$ENDIF}
end;

end.                               
   
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

Gary Randall

  • Jr. Member
  • **
  • Posts: 70
Re: Close CHM window created by TProcess
« Reply #7 on: January 26, 2015, 10:50:02 pm »
Thanks minesadorada.  The code looks good and I'll give it a try in a few days.

Gary
Windows 7 Home Premium 64 bit - SP 1
Lazarus Version #: 1.8.0; FPC Version: 3.0.4
SVN Revision 56594
i386-win32-win32/win64

 

TinyPortal © 2005-2018