Subversion Repositories userdetect2

Rev

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