Subversion Repositories userdetect2

Rev

Rev 73 | Rev 81 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 daniel-mar 1
unit UD2_Main;
2
 
3
interface
4
 
5
{$IF CompilerVersion >= 25.0}
6
{$LEGACYIFEND ON}
7
{$IFEND}
8
 
70 daniel-mar 9
{$INCLUDE 'UserDetect2.inc'}
10
 
68 daniel-mar 11
uses
12
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
13
  Dialogs, StdCtrls, Grids, ValEdit, UD2_Obj, ComCtrls, ImgList, ExtCtrls,
14
  CommCtrl, Menus, VTSListView, VTSCompat;
15
 
16
const
17
  DefaultIniFile = 'UserDetect2.ini';
18
  DefaultWarnIfNothingMatches = 'false';
19
  TagWarnIfNothingMatches = 'WarnIfNothingMatches';
20
  DefaultCloseAfterLaunching = 'false';
21
  TagCloseAfterLaunching = 'CloseAfterLaunching';
22
  TagIcon = 'Icon';
23
 
24
type
25
  TUD2MainForm = class(TForm)
26
    OpenDialog1: TOpenDialog;
27
    PageControl1: TPageControl;
28
    TasksTabSheet: TTabSheet;
29
    TabSheet2: TTabSheet;
30
    TabSheet3: TTabSheet;
31
    IniTemplateMemo: TMemo;
32
    TabSheet4: TTabSheet;
73 daniel-mar 33
    TasksListView: TVTSListView;
34
    TasksImageList: TImageList;
68 daniel-mar 35
    SaveDialog1: TSaveDialog;
36
    TabSheet5: TTabSheet;
37
    Image1: TImage;
38
    Label1: TLabel;
39
    Label2: TLabel;
40
    Label3: TLabel;
41
    Label4: TLabel;
42
    Label5: TLabel;
43
    Label6: TLabel;
44
    Label7: TLabel;
45
    Label8: TLabel;
73 daniel-mar 46
    LoadedPluginsListView: TVTSListView;
47
    IdentificationsListView: TVTSListView;
68 daniel-mar 48
    ErrorsTabSheet: TTabSheet;
49
    ErrorsMemo: TMemo;
50
    Memo1: TMemo;
51
    Panel1: TPanel;
52
    Button1: TButton;
53
    Button2: TButton;
73 daniel-mar 54
    TasksPopupMenu: TPopupMenu;
68 daniel-mar 55
    Run1: TMenuItem;
56
    Properties1: TMenuItem;
73 daniel-mar 57
    IdentificationsPopupMenu: TPopupMenu;
68 daniel-mar 58
    CopyTaskDefinitionExample1: TMenuItem;
59
    Button3: TButton;
60
    VersionLabel: TLabel;
73 daniel-mar 61
    LoadedPluginsPopupMenu: TPopupMenu;
62
    MenuItem1: TMenuItem;
68 daniel-mar 63
    procedure FormDestroy(Sender: TObject);
64
    procedure FormShow(Sender: TObject);
73 daniel-mar 65
    procedure TasksListViewDblClick(Sender: TObject);
66
    procedure TasksListViewKeyPress(Sender: TObject; var Key: Char);
68 daniel-mar 67
    procedure Button1Click(Sender: TObject);
68
    procedure Button2Click(Sender: TObject);
69
    procedure URLLabelClick(Sender: TObject);
73 daniel-mar 70
    procedure TasksPopupMenuPopup(Sender: TObject);
68 daniel-mar 71
    procedure Run1Click(Sender: TObject);
72
    procedure Properties1Click(Sender: TObject);
73 daniel-mar 73
    procedure IdentificationsPopupMenuPopup(Sender: TObject);
68 daniel-mar 74
    procedure CopyTaskDefinitionExample1Click(Sender: TObject);
80 daniel-mar 75
    procedure ListViewCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
68 daniel-mar 76
    procedure Button3Click(Sender: TObject);
73 daniel-mar 77
    procedure LoadedPluginsPopupMenuPopup(Sender: TObject);
78
    procedure MenuItem1Click(Sender: TObject);
68 daniel-mar 79
  protected
80
    ud2: TUD2;
81
    procedure LoadTaskList;
82
    procedure LoadDetectedIDs;
83
    procedure LoadINITemplate;
84
    procedure LoadLoadedPluginList;
85
    function GetIniFileName: string;
86
    procedure DoRun(ShortTaskName: string);
87
    procedure CheckForErrors;
88
  end;
89
 
90
var
91
  UD2MainForm: TUD2MainForm;
92
 
93
implementation
94
 
95
{$R *.dfm}
96
 
97
uses
69 daniel-mar 98
  ShellAPI, Clipbrd, Math, AlphaNumSort, UD2_Utils, UD2_TaskProperties;
68 daniel-mar 99
 
100
type
101
  TUD2ListViewEntry = class(TObject)
102
    ShortTaskName: string;
103
    CloseAfterLaunching: boolean;
104
    TaskPropertiesForm: TForm;
105
  end;
106
 
107
function AddIconRecToImageList(rec: TIconFileIdx; ImageList: TImageList): integer;
108
var
109
  icon: TIcon;
110
begin
111
  icon := TIcon.Create;
112
  try
113
    icon.Handle := ExtractIcon(Application.Handle, PChar(rec.FileName), rec.IconIndex);
114
 
115
    // result := ImageList.AddIcon(ico);
116
    result := AddTransparentIconToImageList(ImageList, icon);
117
  finally
118
    icon.Free;
119
  end;
120
end;
121
 
122
{ TUD2MainForm }
123
 
124
function TUD2MainForm.GetIniFileName: string;
125
resourcestring
126
  LNG_FILE_NOT_FOUND = 'File "%s" not found.';
127
begin
128
  if ParamCount >= 1 then
129
  begin
130
    if FileExists(ParamStr(1)) then
131
    begin
132
      result := ParamStr(1);
133
    end
134
    else
135
    begin
73 daniel-mar 136
      ExitCode := EXITCODE_INI_NOT_FOUND;
68 daniel-mar 137
      MessageDlg(Format(LNG_FILE_NOT_FOUND, [ParamStr(1)]), mtError, [mbOK], 0);
138
      result := '';
139
    end;
140
    Exit;
141
  end
142
  else
143
  begin
144
    if FileExists(DefaultIniFile) then
145
    begin
146
      result := DefaultIniFile;
147
      Exit;
148
    end;
149
 
150
    if FileExists(GetOwnCmdName + '.ini') then
151
    begin
152
      result := GetOwnCmdName + '.ini';
153
      Exit;
154
    end;
155
 
156
    if CompatOpenDialogExecute(OpenDialog1) then
157
    begin
158
      result := OpenDialog1.FileName;
159
      Exit;
160
    end;
161
 
162
    result := '';
163
    Exit;
164
  end;
165
end;
166
 
167
procedure TUD2MainForm.LoadTaskList;
168
var
169
  sl: TStringList;
170
  i: integer;
171
  ShortTaskName, iconString: string;
172
  iconIndex: integer;
173
  obj: TUD2ListViewEntry;
174
begin
73 daniel-mar 175
  TasksListView.Clear;
68 daniel-mar 176
  sl := TStringList.Create;
177
  try
178
    ud2.GetTaskListing(sl);
179
    for i := 0 to sl.Count-1 do
180
    begin
181
      ShortTaskName := sl.Names[i];
182
 
183
      Obj := TUD2ListViewEntry.Create;
184
      Obj.ShortTaskName := ShortTaskName;
185
      Obj.CloseAfterLaunching := ud2.ReadMetatagBool(ShortTaskName, TagCloseAfterLaunching, DefaultCloseAfterLaunching);
186
 
73 daniel-mar 187
      TasksListView.AddItem(sl.Values[ShortTaskName], TObject(Obj));
68 daniel-mar 188
 
189
      iconString := ud2.ReadMetatagString(ShortTaskName, TagIcon, '');
190
      if iconString <> '' then
191
      begin
73 daniel-mar 192
        iconIndex := AddIconRecToImageList(SplitIconString(iconString), TasksImageList);
68 daniel-mar 193
        if iconIndex <> -1 then
194
        begin
73 daniel-mar 195
          TasksListView.Items.Item[TasksListView.Items.Count-1].ImageIndex := iconIndex;
68 daniel-mar 196
        end;
197
      end;
198
    end;
199
  finally
200
    sl.Free;
201
  end;
202
end;
203
 
204
procedure TUD2MainForm.DoRun(ShortTaskName: string);
205
resourcestring
206
  LNG_TASK_NOT_EXISTS = 'The task "%s" does not exist in the INI file.';
207
  LNG_NOTHING_MATCHES = 'No identification string matches to your environment. No application was launched. Please check the Task Definition File.';
208
var
209
  slCmds: TStringList;
210
  i: integer;
211
  cmd: string;
212
begin
213
  if not ud2.TaskExists(ShortTaskName) then
214
  begin
215
    // This can happen if the task name is taken from command line
216
    MessageDlg(Format(LNG_TASK_NOT_EXISTS, [ShortTaskName]), mtError, [mbOK], 0);
73 daniel-mar 217
    ExitCode := EXITCODE_TASK_NOT_EXISTS;
68 daniel-mar 218
    Exit;
219
  end;
220
 
221
  slCmds := TStringList.Create;
222
  try
223
    ud2.GetCommandList(ShortTaskName, slCmds);
224
 
225
    if (slCmds.Count = 0) and
226
      ud2.ReadMetatagBool(ShortTaskName,
227
      TagWarnIfNothingMatches, DefaultWarnIfNothingMatches) then
228
    begin
229
      MessageDlg(LNG_NOTHING_MATCHES, mtWarning, [mbOK], 0);
73 daniel-mar 230
    ExitCode := EXITCODE_TASK_NOTHING_MATCHES;
68 daniel-mar 231
    end;
232
 
233
    for i := 0 to slCmds.Count-1 do
234
    begin
235
      cmd := slCmds.Strings[i];
236
      if cmd = '' then continue;
80 daniel-mar 237
      UD2_RunCMD(cmd, SW_NORMAL); // Idea: let SW_NORMAL be configurable by the user?
68 daniel-mar 238
    end;
239
  finally
240
    slCmds.Free;
241
  end;
242
end;
243
 
244
procedure TUD2MainForm.FormDestroy(Sender: TObject);
245
var
246
  i: integer;
247
begin
248
  if Assigned(ud2) then ud2.Free;
73 daniel-mar 249
  for i := 0 to TasksListView.Items.Count-1 do
68 daniel-mar 250
  begin
73 daniel-mar 251
    TUD2ListViewEntry(TasksListView.Items.Item[i].Data).Free;
68 daniel-mar 252
  end;
253
end;
254
 
255
procedure TUD2MainForm.CheckForErrors;
256
begin
257
  ErrorsTabSheet.TabVisible := ud2.Errors.Count > 0;
258
  if ErrorsTabSheet.TabVisible then
259
  begin
260
    ErrorsMemo.Lines.Assign(ud2.Errors);
261
    PageControl1.ActivePage := ErrorsTabSheet;
262
  end;
263
end;
264
 
265
procedure TUD2MainForm.LoadDetectedIDs;
266
var
267
  i, j: integer;
268
  pl: TUD2Plugin;
269
  ude: TUD2IdentificationEntry;
270
begin
73 daniel-mar 271
  IdentificationsListView.Clear;
68 daniel-mar 272
  for i := 0 to ud2.LoadedPlugins.Count-1 do
273
  begin
274
    pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
275
    for j := 0 to pl.DetectedIdentifications.Count-1 do
276
    begin
277
      ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry;
73 daniel-mar 278
      with IdentificationsListView.Items.Add do
68 daniel-mar 279
      begin
280
        Caption := pl.PluginName;
281
        SubItems.Add(pl.IdentificationMethodName);
282
        SubItems.Add(ude.IdentificationString);
283
        SubItems.Add(GUIDToString(pl.PluginGUID));
284
      end;
285
    end;
286
  end;
287
 
73 daniel-mar 288
  for i := 0 to IdentificationsListView.Columns.Count-1 do
68 daniel-mar 289
  begin
73 daniel-mar 290
    IdentificationsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
68 daniel-mar 291
  end;
292
end;
293
 
294
procedure TUD2MainForm.LoadINITemplate;
295
var
296
  i, j: integer;
297
  pl: TUD2Plugin;
298
  ude: TUD2IdentificationEntry;
299
begin
300
  IniTemplateMemo.Clear;
301
  IniTemplateMemo.Lines.Add('[ExampleTask1]');
302
  IniTemplateMemo.Lines.Add('; Description: Optional but recommended');
303
  IniTemplateMemo.Lines.Add('Description=Run Task #1');
304
  IniTemplateMemo.Lines.Add('; WarnIfNothingMatches: Warns when no application was launched. Default: false.');
305
  IniTemplateMemo.Lines.Add('WarnIfNothingMatches=false');
306
  IniTemplateMemo.Lines.Add('; Optional: IconDLL + IconIndex');
307
  IniTemplateMemo.Lines.Add('Icon=%SystemRoot%\system32\Shell32.dll,3');
308
  IniTemplateMemo.Lines.Add('; Optional: Can be true or false');
309
  IniTemplateMemo.Lines.Add(TagCloseAfterLaunching+'=true');
310
 
311
  for i := 0 to ud2.LoadedPlugins.Count-1 do
312
  begin
313
    pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
314
    for j := 0 to pl.DetectedIdentifications.Count-1 do
315
    begin
316
      ude := pl.DetectedIdentifications.Items[j] as TUD2IdentificationEntry;
317
      IniTemplateMemo.Lines.Add(Format('; %s', [ude.Plugin.PluginName]));
318
      IniTemplateMemo.Lines.Add(ude.GetPrimaryIdName+'=calc.exe');
319
    end;
320
  end;
321
end;
322
 
323
procedure TUD2MainForm.LoadLoadedPluginList;
69 daniel-mar 324
resourcestring
325
  LNG_MS = '%dms';
68 daniel-mar 326
var
327
  i: integer;
328
  pl: TUD2Plugin;
329
begin
73 daniel-mar 330
  LoadedPluginsListView.Clear;
68 daniel-mar 331
  for i := 0 to ud2.LoadedPlugins.Count-1 do
332
  begin
333
    pl := ud2.LoadedPlugins.Items[i] as TUD2Plugin;
73 daniel-mar 334
    with LoadedPluginsListView.Items.Add do
68 daniel-mar 335
    begin
336
      Caption := pl.PluginDLL;
337
      SubItems.Add(pl.PluginVendor);
338
      SubItems.Add(pl.PluginName);
339
      SubItems.Add(pl.PluginVersion);
340
      SubItems.Add(pl.IdentificationMethodName);
70 daniel-mar 341
      SubItems.Add(IntToStr(pl.DetectedIdentifications.Count));
69 daniel-mar 342
      SubItems.Add(Format(LNG_MS, [Max(1,pl.time)])); // at least show 1ms, otherwise it would be unloggical
70 daniel-mar 343
      SubItems.Add(pl.IdentificationProcedureStatusCodeDescribed);
68 daniel-mar 344
      SubItems.Add(pl.PluginGUIDString);
345
    end;
346
  end;
347
 
73 daniel-mar 348
  for i := 0 to LoadedPluginsListView.Columns.Count-1 do
68 daniel-mar 349
  begin
73 daniel-mar 350
    LoadedPluginsListView.Columns.Items[i].Width := LVSCW_AUTOSIZE_USEHEADER;
68 daniel-mar 351
  end;
352
end;
353
 
354
procedure TUD2MainForm.FormShow(Sender: TObject);
355
resourcestring
356
  LNG_SYNTAX = 'Syntax: %s [TaskDefinitionFile [TaskName]]';
357
var
358
  LoadedIniFile: string;
359
begin
73 daniel-mar 360
  ExitCode := EXITCODE_OK;
361
 
68 daniel-mar 362
  // To avoid accidental changes from the GUI designer
363
  PageControl1.ActivePage := TasksTabSheet;
364
 
365
  if ((ParamCount = 1) and (ParamStr(1) = '/?')) or (ParamCount >= 3) then
366
  begin
73 daniel-mar 367
    ExitCode := EXTICODE_SYNTAX_ERROR;
68 daniel-mar 368
    MessageDlg(Format(LNG_SYNTAX, [GetOwnCmdName]), mtInformation, [mbOK], 0);
369
    Close;
370
    Exit;
371
  end;
372
 
373
  LoadedIniFile := GetIniFileName;
374
  if LoadedIniFile = '' then
375
  begin
376
    Close;
377
    Exit;
378
  end;
379
  ud2 := TUD2.Create(LoadedIniFile);
380
 
80 daniel-mar 381
  ud2.HandlePluginDir('',        '*.smp');
382
  ud2.HandlePluginDir('Plugins', '*.smp');
383
  ud2.HandlePluginDir('Plugins', '*.dll');
68 daniel-mar 384
 
385
  if ParamCount >= 2 then
386
  begin
387
    DoRun(ParamStr(2));
388
    Close;
389
    Exit;
390
  end
391
  else
392
  begin
393
    LoadTaskList;
394
    LoadDetectedIDs;
395
    LoadINITemplate;
396
    LoadLoadedPluginList;
397
    CheckForErrors;
398
  end;
399
end;
400
 
73 daniel-mar 401
procedure TUD2MainForm.TasksListViewDblClick(Sender: TObject);
68 daniel-mar 402
var
403
  obj: TUD2ListViewEntry;
404
begin
73 daniel-mar 405
  if TasksListView.ItemIndex = -1 then exit;
406
  obj := TUD2ListViewEntry(TasksListView.Selected.Data);
68 daniel-mar 407
  DoRun(obj.ShortTaskName);
408
  if obj.CloseAfterLaunching then Close;
409
end;
410
 
73 daniel-mar 411
procedure TUD2MainForm.TasksListViewKeyPress(Sender: TObject; var Key: Char);
68 daniel-mar 412
begin
413
  if Key = #13 then
414
  begin
73 daniel-mar 415
    TasksListViewDblClick(Sender);
68 daniel-mar 416
  end;
417
end;
418
 
419
procedure TUD2MainForm.Button1Click(Sender: TObject);
420
begin
421
  UD2_RunCMD(ud2.IniFileName, SW_NORMAL);
422
end;
423
 
424
procedure TUD2MainForm.Button2Click(Sender: TObject);
425
begin
426
  if CompatSaveDialogExecute(SaveDialog1) then
427
  begin
428
    IniTemplateMemo.Lines.SaveToFile(SaveDialog1.FileName);
429
  end;
430
end;
431
 
432
procedure TUD2MainForm.URLLabelClick(Sender: TObject);
433
var
434
  s: string;
435
begin
436
  s := TLabel(Sender).Caption;
437
  if Pos('@', s) > 0 then
438
    s := 'mailto:' + s
439
  else
440
    s := 'http://' + s;
441
  UD2_RunCMD(s, SW_NORMAL);
442
end;
443
 
73 daniel-mar 444
procedure TUD2MainForm.TasksPopupMenuPopup(Sender: TObject);
68 daniel-mar 445
begin
73 daniel-mar 446
  Run1.Enabled := TasksListView.ItemIndex <> -1;
447
  Properties1.Enabled := TasksListView.ItemIndex <> -1;
68 daniel-mar 448
end;
449
 
450
procedure TUD2MainForm.Run1Click(Sender: TObject);
451
begin
73 daniel-mar 452
  TasksListViewDblClick(Sender);
68 daniel-mar 453
end;
454
 
455
procedure TUD2MainForm.Properties1Click(Sender: TObject);
456
var
457
  obj: TUD2ListViewEntry;
458
begin
73 daniel-mar 459
  if TasksListView.ItemIndex = -1 then exit;
460
  obj := TUD2ListViewEntry(TasksListView.Selected.Data);
68 daniel-mar 461
  if obj.TaskPropertiesForm = nil then
462
  begin
463
    obj.TaskPropertiesForm := TUD2TaskPropertiesForm.Create(Self, ud2, obj.ShortTaskName);
464
  end;
465
  obj.TaskPropertiesForm.Show;
466
end;
467
 
73 daniel-mar 468
procedure TUD2MainForm.IdentificationsPopupMenuPopup(Sender: TObject);
68 daniel-mar 469
begin
73 daniel-mar 470
  CopyTaskDefinitionExample1.Enabled := IdentificationsListView.ItemIndex <> -1;
68 daniel-mar 471
end;
472
 
473
procedure TUD2MainForm.CopyTaskDefinitionExample1Click(Sender: TObject);
474
var
475
  s: string;
476
begin
73 daniel-mar 477
  s := '; '+IdentificationsListView.Selected.Caption+#13#10+
478
       IdentificationsListView.Selected.SubItems[0] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10+
68 daniel-mar 479
       #13#10+
480
       '; Alternatively:'+#13#10+
73 daniel-mar 481
       IdentificationsListView.Selected.SubItems[2] + ':' + IdentificationsListView.Selected.SubItems[1] + '=calc.exe'+#13#10;
68 daniel-mar 482
  Clipboard.AsText := s;
483
end;
484
 
485
procedure TUD2MainForm.ListViewCompare(Sender: TObject; Item1,
486
  Item2: TListItem; Data: Integer; var Compare: Integer);
487
var
488
  ListView: TVTSListView;
489
begin
490
  ListView := Sender as TVTSListView;
491
  if ListView.CurSortedColumn = 0 then
492
  begin
69 daniel-mar 493
    Compare := AlphaNumCompare(Item1.Caption, Item2.Caption);
68 daniel-mar 494
  end
495
  else
496
  begin
69 daniel-mar 497
    Compare := AlphaNumCompare(Item1.SubItems[ListView.CurSortedColumn-1],
498
                               Item2.SubItems[ListView.CurSortedColumn-1]);
68 daniel-mar 499
  end;
500
  if ListView.CurSortedDesc then Compare := -Compare;
501
end;
502
 
503
procedure TUD2MainForm.Button3Click(Sender: TObject);
504
begin
505
  VTS_CheckUpdates('userdetect2', VersionLabel.Caption);
506
end;
507
 
73 daniel-mar 508
procedure TUD2MainForm.LoadedPluginsPopupMenuPopup(Sender: TObject);
509
begin
510
  MenuItem1.Enabled := LoadedPluginsListView.ItemIndex <> -1;
511
end;
512
 
513
procedure TUD2MainForm.MenuItem1Click(Sender: TObject);
514
var
515
  s: string;
516
begin
80 daniel-mar 517
  s := '; ' + LoadedPluginsListView.Selected.SubItems.Strings[6];
73 daniel-mar 518
  Clipboard.AsText := s;
519
end;
520
 
68 daniel-mar 521
end.