Solved

How to call a CLSID Column Handler function to get the result string?

Posted on 2010-09-10
28
990 Views
Last Modified: 2013-11-18
Hello,

I want to call a function of a Column Handler / InfoTip ActiveX.

Its of Embird Embroidery Software.

The software created a explorer column handler, to show embroidery file stitches count and other file  data.

How do i call this function to get the result string?

or how can i call the following method to get the resulting string?:
{DB8853E3-33CC-447E-84AA-FC319381A97B}6

this seems to be a CLSID id,Index (of column handler)

Here a InfoTip Registry Data of a .emb file, registered as: EMBIRd.file.emb under HKEY_CLASSES_ROOT

InfoTip REG_SZ "prop:Name;{DB8853E3-33CC-447E-84AA-FC319381A97B}6;{DB8853E3-33CC-447E-84AA-FC319381A97B}10;Type;Size;create;write;access;DocTitle;DocSubject;DocAuthor;DocCategory;DocComments"

QuickTip REG_SZ "prop:{DB8853E3-33CC-447E-84AA-FC319381A97B}6;Size"
TileInfo REG_SZ "prop:{DB8853E3-33CC-447E-84AA-FC319381A97B}6;Size"

You can see a screenshot bellow.
infotip.JPG
0
Comment
Question by:BiggBrotha
  • 13
  • 11
  • 3
28 Comments
 
LVL 14

Expert Comment

by:systan
ID: 33652313
something like that?
if that's the step to get what you want, please indicate what's next?
unit Unit1;



interface



uses Registry,

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;



type

  TForm1 = class(TForm)

    Button1: TButton;

    ListBox1: TListBox;

    procedure Button1Click(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;



var

  Form1: TForm1;

  tS: TStringList;



implementation



{$R *.dfm}







procedure ReadCLSID;

var

  MyReg: TRegistry;

begin

  ts := TStringList.Create;

  MyReg := TRegistry.Create(KEY_EXECUTE);

   with MyReg do

    try

       RootKey := HKEY_CLASSES_ROOT;

       OpenKey('Clsid',false);

       GetKeyNames(ts);

    finally

       CloseKey;

       Free;

    end;

end;





procedure TForm1.Button1Click(Sender: TObject);

var i:integer;

begin

ReadCLSID;

Listbox1.Items := ts;

Caption := inttostr(Listbox1.Items.count);

for i := 0 to Listbox1.Items.count-1 do

begin

if listbox1.items[i]='{DB8853E3-33CC-447E-84AA-FC319381A97B}' then

begin

showmessage('found: ' + listbox1.items[i]);

exit;

end;

end;

end;



end.

Open in new window

0
 

Author Comment

by:BiggBrotha
ID: 33652337
No, this will read Registry Keys.
i want toquery
0
 

Author Comment

by:BiggBrotha
ID: 33652339
No, this will read Registry Keys.

i want to query the function number 6 of this activex object {DB8853E3-33CC-447E-84AA-FC319381A97B}
to return something like:

54.8x87.2mm, 3619st, 5/5clrs
0
 
LVL 14

Expert Comment

by:systan
ID: 33652353
quering is reading
so, you must read first the {DB8853E3-33CC-447E-84AA-FC319381A97B} to get 6, then return 54.8x87.2mm, 3619st, 5/5clrs

I'll take a look
0
 
LVL 14

Expert Comment

by:systan
ID: 33652359
Ok, can you save your registry and attach it, so I can see whats the structure inside.
To attach, just click file, then browse your save reg
0
 
LVL 14

Expert Comment

by:systan
ID: 33652413
But probably I would not see your registry;
try to use this component;

unit TipTreeView;



interface



uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

ComCtrls;



type

TInfoTipEvent = procedure(Sender: TObject; Item: TTreeNode;

var InfoTip: string) of object;

TTipTreeView = class(TTreeView)

private

FOnInfoTip: TInfoTipEvent;

published

property OnInfoTip: TInfoTipEvent read FOnInfoTip write FOnInfoTip;

public

procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW;

end;



procedure Register;



implementation



procedure Register;

begin

RegisterComponents('Samples', [TTipTreeView]);

end;



procedure TTipTreeView.CMHintShow(var Message: TMessage);

var

Item: TTreeNode;

ItemRect: TRect;

InfoTip: string;

begin

if Assigned(FOnInfoTip) then

with TCMHintShow(Message) do

begin

Item := GetNodeAt(HintInfo.CursorPos.X, HintInfo.CursorPos.Y);

if Item <> nil then

begin

InfoTip := Item.Text;

if Assigned(FOnInfoTip) then FOnInfoTip(Self, Item, InfoTip);

ItemRect := Item.DisplayRect(False);

ItemRect.TopLeft := ClientToScreen(ItemRect.TopLeft);

ItemRect.BottomRight := ClientToScreen(ItemRect.BottomRight);

with HintInfo^ do

begin

HintInfo^.CursorRect := ItemRect;

HintInfo^.HintStr := InfoTip;

HintPos.Y := CursorRect.Top + GetSystemMetrics(SM_CYCURSOR);

HintPos.X := CursorRect.Left + GetSystemMetrics(SM_CXCURSOR);

GetSystemMetrics(SM_CXCURSOR);

HintInfo^.HintMaxWidth := ClientWidth;

Message.Result := 0;

end

end;

end

else

inherited;

end;



end.

Open in new window

0
 

Author Comment

by:BiggBrotha
ID: 33652594
here is the registry


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\EMBIRD.File.emb]
"InfoTip"="prop:Name;{DB8853E3-33CC-447E-84AA-FC319381A97B}6;{DB8853E3-33CC-447E-84AA-FC319381A97B}10;Type;Size;create;write;access;DocTitle;DocSubject;DocAuthor;DocCategory;DocComments"
"QuickTip"="prop:{DB8853E3-33CC-447E-84AA-FC319381A97B}6;Size"
"TileInfo"="prop:{DB8853E3-33CC-447E-84AA-FC319381A97B}6;Size"
@="EMB File"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\DefaultIcon]
@="%1"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\PredchadzajucaAsociacia]
@="ES.Documento"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\convert]
@="&Convert"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\convert\command]
@="\"C:\\Program Files\\EMBIRD32\\EMBIRD.EXE\" \"%1\" /C"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\edit]
@="&Edit"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\edit\command]
@="\"C:\\Program Files\\EMBIRD32\\EMBIRD.EXE\" \"%1\" /E"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\open]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\open\command]
@="\"C:\\Program Files\\EMBIRD32\\EMBIRD.EXE\" \"%1\""

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\print]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\print\command]
@="\"C:\\Program Files\\EMBIRD32\\EMBIRD.EXE\" \"%1\" /P"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\quickview]
@="&Quick View"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shell\quickview\command]
@="\"C:\\Program Files\\EMBIRD32\\VIEWER.EXE\" \"%1\""

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\ContextMenuHandlers]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\ContextMenuHandlers\EmbirdCH]
@="{18D7FD25-4D7C-11D6-AB9F-8FE66DD3F034}"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\IconHandler]
@="{6B44F8C0-6D93-11D5-A405-0040C72E0001}"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\PropertySheetHandlers]

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\PropertySheetHandlers\EmbirdPS]
@="{BE0E21B1-AA13-4786-BCB3-0A97F641F23E}"

[HKEY_CLASSES_ROOT\EMBIRD.File.emb\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}]
@="{A81E778C-14EF-49B0-BC12-E7980ECC51EF}"
0
 
LVL 14

Expert Comment

by:systan
ID: 33653244
Now where is 54.8x87 in your registry?  Did you find it?
0
 

Author Comment

by:BiggBrotha
ID: 33653398
No, because it is not in registry . It's returned by a dynamic   Activex function identified by the following Clsid {DB8853E3-33CC-447E-84AA-FC319381A97B}6, and the 6 is probably a column handler index function of this activex control. I want to know how to call this function to get the resulting string that is processed by this activex control , and probably uses the filename as only parameter to show file info ( total stitches , colors and so on ) but I don't need to know how this activex parse the file to get the data , I only need to know how windows calls this function to show in explorer the resulting information. I have found so much howtos teaching how to create these active x controls. but i dont need to create i need to use An existing control. these explorer activex controls are known by column handlers, infotip handlers , thumbnail handlers and so on.
0
 
LVL 14

Expert Comment

by:systan
ID: 33653572
54.8x87.2mm is a dimension? image dimension?
0
 
LVL 14

Expert Comment

by:systan
ID: 33653582
Do you want to get the return when file is clicked? or when file is pointed?
0
 

Author Comment

by:BiggBrotha
ID: 33653609
I want to know how pragmatically using win32 API / activex  call the column handler function passing a file path as parameter to get the function result string . The dimension is of the embroidery file read by embroidery machines that has a proprietary format , it's not an image . It's a file with instructions and coordinates to the machine.
0
 
LVL 14

Expert Comment

by:systan
ID: 33655273
This is the other way to get the dimension of your .EMB file.
Just use AnsiPos to position it.
unit Unit1;



interface



uses  CommCtrl, uProcessMemMgr,

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ExtCtrls;



type

  TForm1 = class(TForm)

    Timer1: TTimer;

    procedure Timer1Timer(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



function ActiveCaption: string;

var

Handle: THandle;

Len: LongInt;

Title: string;

begin

Result := '';

Handle := GetForegroundWindow;

if Handle <> 0 then

begin

Len := GetWindowTextLength(Handle) + 1;

SetLength(Title, Len);

GetWindowText(Handle, PChar(Title), Len);

ActiveCaption := TrimRight(Title);

end;

end;



function GetStatusBarText(hStatusBarHandle: HWND; PanelNumber: Integer): string;

var

  PMM: TProcessMemMgr;

  NumberOfPanels, Len: Integer;

  PrcBuf: PChar;

  PartText: string;

begin

  if hStatusBarHandle = 0 then Exit;

  PMM := CreateProcessMemMgrForWnd(hStatusBarHandle);

  try

    NumberOfPanels := SendMessage(hStatusBarHandle, SB_GETPARTS, 0, 0);

    if PanelNumber < NumberOfPanels then

    begin

      Len := LOWORD(SendMessage(hStatusBarHandle, SB_GETTEXTLENGTH, PanelNumber, 0));

      if Len > 0 then

      begin

        PrcBuf := PMM.AllocMem(Len + 1);

        SendMessage(hStatusBarHandle, SB_GETTEXT, PanelNumber, Longint(PrcBuf));

        Result := PMM.ReadStr(PrcBuf);

        PMM.FreeMem(PrcBuf);

      end

      else

      begin

        Result := '';

      end;

    end;

  finally

    PMM.Free;

  end;

end;



procedure TForm1.Timer1Timer(Sender: TObject);

var

  hWindow, hStatusBarHandle: HWND;

  char1:pchar;

begin

char1 := pchar(activecaption);

hWindow:= FindWindow(nil, char1);

hStatusBarHandle := FindWindowEx(hWindow, 0, 'msctls_statusbar32', nil);

Form1.Caption := GetStatusBarText(hStatusBarHandle,0);

end;



end.

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:BiggBrotha
ID: 33655350
This works but need a person to interact with the explorer window.

i need a function like:

GetEMBInformation(fileName:string):string;


so i can feed the function with a filename and get the results.

must be a way to make the call to the activex control, like windows explorer do.
0
 
LVL 14

Expert Comment

by:systan
ID: 33655793
If you need an ActiveX,  it would overwrite the infoTIP.

iS that what you want? Overwrite the infoTIP to get what you want?

OR leave the infoTIP alone and make your own goal to get the dimension?
0
 
LVL 14

Expert Comment

by:systan
ID: 33655814
If you need an ActiveX,   it would overwrite the infoTIP.

iS that what you want?  Overwrite the infoTIP to get what you want?

OR leave the infoTIP alone and make your own goal to get the dimension?

If you really want to make your own infoTIP to get what you want and overwrite the old infoTIP that you have, try that link;
http://www.agnisoft.com/delphi/dfminfotip.zip
And don't forget to register it with regsvr32
0
 
LVL 14

Expert Comment

by:systan
ID: 33655835
Ok;
>>i need a function like:
>>GetEMBInformation(fileName:string):string;

Here's the activeX code;
infoTIP.zip
0
 

Author Comment

by:BiggBrotha
ID: 33656387
This is not what I want. please understand..

You provided a code that create an infotip.

  // show a very basic infotip
  ppwszTip := StringToOleStr('The infotip for: ' + #13 + fName);
  Result := S_OK;

I don't want to create an infotip.
I want to grab 3rd party infotips data.

lets assume that you created this infotip that you sent and registered the .dll. when i mousehover the file its show:
The infotip for: Filename .

I want to have access to this function that you created. from another delphi application.

like:
function GetSystanInfotip:string external 'systaninfotip.dll';
0
 
LVL 14

Expert Comment

by:systan
ID: 33656443
>>I don't want to create an infotip.
>>I want to grab 3rd party infotips data.

Ok well leave the infoTIP alone and make our own goal to get the dimension.
And I think you know better than me in terms of infoTIP,  let me think if I can help you further more, nevertheless I am capable of this or not,  I will try to help.
0
 

Author Comment

by:BiggBrotha
ID: 33656796
I think that what this guy tried to do , is the same thing i'm trying to do.

http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.ole/2004-07/0230.html


i tryed to convert to delphi but its givin-me access violation errors


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,activex,shlobj,shellapi, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function SHILCreateFromPath(Path: Pointer; PIDL: PItemIDList; var Attributes: Cardinal): HResult; stdcall;

var
  Form1: TForm1;

  const IID_IQueryInfo: TGUID = '{DB8853E3-33CC-447E-84AA-FC319381A97B}';
//  const IID_IQueryInfo: TGUID = '{84F26EA0-42A0-1069-A2E3-08002B30309D}';
implementation

const Shell32DLL = 'shell32.dll';

function SHILCreateFromPath(Path: Pointer; PIDL: PItemIDList; var Attributes: Cardinal): HResult; external Shell32DLL name 'SHILCreateFromPath';

{$R *.dfm}


function GetInfoTip( psf:IShellFolder; pidl:PItemIdList; pszText:LPTSTR; cchTextMax:integer):boolean;
var pqi:IQueryInfo;
pwszTip:PWideChar;
begin
        Result:=False;
        pszText:='';

        if ( Assigned(pidl) )
        then begin

                if ( SUCCEEDED( psf.GetUIObjectOf( 0, 1, pidl, IID_IQueryInfo, nil, Pointer(pqi) ) ) )
                then begin
                        // assuming Unicode
                        pqi.GetInfoTip( 0, pwszTip );
                        if ( Assigned(pwszTip) )
                        then begin
                                Result:=True;
                                lstrcpyn( pszText, pchar(pwszTip), cchTextMax );
                                //SHFree( pwszTip );
                                CoTaskMemFree(pwszTip);
                        end;
                        pqi._Release;
                end;
        end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var infoTip:string;
var path:string[255];
shFolder:IShellFolder;
pidl:PITEMIDLIST;
a:cardinal;
begin
a:=0;
path:='c:\Design\Bird.EMB';
        SHGetDesktopFolder( shFolder );
        SHILCreateFromPath( @path, pidl, a );
        GetInfoTip( shFolder, pidl, pchar(infoTip), 255 );
       showmessage(infotip);
end;

end.

Open in new window

0
 
LVL 14

Assisted Solution

by:systan
systan earned 50 total points
ID: 33656935
Am, same happens.
I hope epasquier, aflarin, geert and thievingsix are here,  they are more advance than us.
Let's wait, I hope there listening.  Meantime I'll check the code.
0
 

Author Comment

by:BiggBrotha
ID: 33656973
I made some progress,

Got a function from Jedi that grabs item infotips, its almost the same function but does not contain errors due to C++ to delphi convertion.

and the program still reproducing access violations.

But if i inspect the variables in delphi breakpoint & debugger: it shows the guys message:

'Shows the files, folders, program shortcuts, and other items on the desktop.'

So the function is grabbing Desktop Infotip, we just need to find a way to change these functions:

path:='c:/Design/Bird.EMB';
SHGetDesktopFolder( shFolder );
SHILCreateFromPath(@path, pidl, a );

pointing to a file. i think that is a function with same properties that SHGetDesktopFolder but something like "SHGetFolder" accepting the folder as param and shFolder as output result.
function SHFreeMem(var P: Pointer): Boolean;

var

  Malloc: IMalloc;

begin

  Result := False;

  if P <> nil then

  begin

    if Succeeded(SHGetMalloc(Malloc)) and (Malloc.DidAlloc(P) > 0) then

    begin

      Malloc.Free(P);

      P := nil;

      Result := True;

    end;

  end;

end;





function SHGetItemInfoTip(const Folder: IShellFolder; Item: PItemIdList): string;

var

  QueryInfo: IQueryInfo;

  InfoTip: PWideChar;

begin

  Result := '';

  if (Item = nil) or (Folder = nil) then

    Exit;

  if Succeeded(Folder.GetUIObjectOf(0, 1, Item, IQueryInfo, nil,

    Pointer(QueryInfo))) then

  begin

    if Succeeded(QueryInfo.GetInfoTip(0, InfoTip)) then

    begin

      Result := WideCharToString(InfoTip);

      SHFreeMem(Pointer(InfoTip));

    end;

  end;

end;

Open in new window

0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33658799
Do it like this, you have to get to the exact file itself

function TForm1.GetToolTip(const AFileName: string): string;
var
  DesktopFolder, FileFolder: IShellFolder;
  pidl, filePidl: PItemIdList;
  QueryInfo: IQueryInfo;
  foldername, filename: string;
  pEaten, pAttribs: Cardinal;
  InfoTip: PWideChar;
begin
  foldername := ExtractFileDir(AFileName);
  filename := ExtractFileName(AFileName);

  SHGetDesktopFolder(desktopFolder);

  DesktopFolder.ParseDisplayName(Handle, nil, PWideChar(folderName), pEaten, pidl, pAttribs);

  DesktopFolder.BindToObject(pidl, nil, IID_IShellFolder, FileFolder);

  FileFolder.ParseDisplayName(Handle, nil, PWideChar(filename), pEaten, filePidl, pAttribs);
 
  FileFolder.GetUIObjectOf(0, 1, filePidl, IID_IQueryInfo, 0, Pointer(QueryInfo));

  if Succeeded(QueryInfo.GetInfoTip(0, InfoTip)) then
  begin
    Result:= WideCharToString(InfoTip);
    SHFreeMem(Pointer(InfoTip));
  end;
end;

0
 

Author Comment

by:BiggBrotha
ID: 33658944
Its givin-me access violation error on line:

FileFolder.ParseDisplayName(Handle, nil, PWideChar(filename), pEaten, filePidl, pAttribs);

i tried to figure out why, but i didn't had success.

I don't know what to do.

Please help?
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 33659057
Are you using Delphi 7

You have to change the line to
DesktopFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(folderName)), pEaten, pidl, pAttribs);

Use this
function TForm1.GetToolTip(const AFileName: string): string;
var
  DesktopFolder, FileFolder: IShellFolder;
  pidl, filePidl: PItemIdList;
  QueryInfo: IQueryInfo;
  foldername, filename: string;
  pEaten, pAttribs: Cardinal;
  InfoTip: PWideChar;
  hr: HResult;
begin
  foldername := ExtractFileDir(AFileName);
  filename := ExtractFileName(AFileName);

  SHGetDesktopFolder(desktopFolder);

  DesktopFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(folderName)), pEaten, pidl, pAttribs);

  if Succeeded(DesktopFolder.BindToObject(pidl, nil, IID_IShellFolder, FileFolder)) then
  begin
    FileFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(filename)), pEaten, filePidl, pAttribs);
    FileFolder.GetUIObjectOf(0, 1, filePidl, IID_IQueryInfo, 0, Pointer(QueryInfo));

    if Succeeded(QueryInfo.GetInfoTip(0, InfoTip)) then
    begin
      Result := WideCharToString(InfoTip);
      SHFreeMem(Pointer(InfoTip));
    end;
  end;
end;
0
 
LVL 32

Accepted Solution

by:
ewangoya earned 450 total points
ID: 33659083
To view any errors generated when calling the functions, add ComObj to your uses clause and use OleCheck on the functions instead of Succeeded. Succeeded does not return you any error message or code.

e.g.
  OleCheck(DesktopFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(folderName)), pEaten, pidl, pAttribs));
 OleCheck(Succeeded(DesktopFolder.BindToObject(pidl, nil, IID_IShellFolder, FileFolder)) )
 OleCheck(FileFolder.ParseDisplayName(Handle, nil, PWideChar(WideString(filename)), pEaten, filePidl, pAttribs));
 OleCheck(FileFolder.GetUIObjectOf(0, 1, filePidl, IID_IQueryInfo, 0, Pointer(QueryInfo)));

This way you will get the exact error generated by the function call

If you need more help let me know
0
 

Author Closing Comment

by:BiggBrotha
ID: 33660902
Thanks
0

Featured Post

Promote certifications in your email signature

Has your company recently won an award or achieved a certification? They'll no doubt want to show it off. Email signature images used to promote certifications & awards can instantly establish credibility with a recipient and provide you with numerous benefits.

Join & Write a Comment

Suggested Solutions

The use of stolen credentials is a hot commodity this year allowing threat actors to move laterally within the network in order to avoid breach detection.
Sometimes drives fill up and we don't know why.  If you don't understand the best way to use the tools available, you may end up being stumped as to why your drive says it's not full when you have no space left!  Here's how you can find out...
This Micro Tutorial will give you a basic overview of Windows DVD Burner through its features and interface. This will be demonstrated using Windows 7 operating system.
The Task Scheduler is a powerful tool that is built into Windows. It allows you to schedule tasks (actions) on a recurring basis, such as hourly, daily, weekly, monthly, at log on, at startup, on idle, etc. This video Micro Tutorial is a brief intro…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now