Solved

Explorer window position

Posted on 2000-05-07
16
486 Views
Last Modified: 2010-04-04
How can I set and get the windows explorer window position. I would like to set one folders window position and then use that position for all subfolders of the root folder.
Example: Open a folder in explorer, move and resize the explorer window where i want it, then everytime I open that folder, or any folder below that folder in the position i have set. There used to be a file called desktop.ini, I don't know if this file is the file to use, or whether there is an API call or registry entry to watch.

Please help
0
Comment
Question by:JasonC
  • 9
  • 7
16 Comments
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Hmmm... You mean you want to set the folder options settings (or how it is called)?
Perhaps you should download the free tools "RegMon" and "FileMon" from here:

www.sysinternals.com

This tools shows you all accesses to the registry respectively to any files. So you could start the tool, then change the settings manually, then look what registry keys and what files are changed.

Regards, Madshi.
0
 

Author Comment

by:JasonC
Comment Utility
no apparent changes are taking place either in the registry of the file system, apart from changes to my .log file, but I doubt it is there. Values are read in the registry, but coordinates etc are not written anywhere I can find. Another option i could have is to have preset positions for the windows. But I am using ShellExecute to launch the explorer, which returns either an instance handle or a DDE handle, so how can I use something like MoveWindow to move the explorer window where i want it?
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
:-(  Well, what you could do is enumerate the main windows (the windows that are in the taskbar) of the explorer before and after you called ShellExecute. The one window that is new, should be the one that was opened by ShellExecute.
You can use my free unit "enumStuff" from my homepage:

http://beam.to/madshi

to enumerate the running processes (to find the explorer's processID) and to enumerate the main windows of a given processID. (enumStuff works only with D4+D5).

Regards, Madshi.
0
 

Author Comment

by:JasonC
Comment Utility
Hi Madshi

Thanks for the info, i will look into this, although I am using D3 and don't want to convert the project to D5.

Regards
Jason
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Well, then you can use this to find the processID of the explorer:

var explorer : dword;
begin
  explorer := FindWindow('Shell_TrayWnd', '');
  if explorer <> 0 then
    GetWindowThreadProcessID(explorer, @explorer);

Now in explorer you should find the processID. So you can forget about the process enumeration.

If you want to know how to enumerate the main windows of this processID, look at the sources of enumStuff, function "GetWindowList".

Regards, Madshi.
0
 

Author Comment

by:JasonC
Comment Utility
Adjusted points from 200 to 400
0
 

Author Comment

by:JasonC
Comment Utility
Hi Madshi,

Well I tried, but can't figure out how to do this, So I'm upping the points to 400 and hope that either you or someone else can get this working, I need to be able to send a folder string to a procedure and have that procedure load the explorer and move and resize the window to a location and size specified. I wouldn't think it should be that biger a deal, but of course making things like this simple is a long drawn out process. I did try getting the code you suggested working, and I did get the window titles etc. but I can see a lot of problems with this, like some windows options, of displaying the full path in the title bar etc.

So I hope someone can get this going for me.

Thank you
Jason
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
>> I did try getting the code you suggested working, and I did get the window titles etc. but I can see a lot of problems with this, like some windows options, of displaying the full path in the title bar etc.

Ehm, what about the windows options? We didn't talk about them yet. What do you mean? I can write that code for you, but that doesn't include any windows options...

Regards, Madshi.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:JasonC
Comment Utility
I meant the windows options that are built into windows 95, 98 etc.
I thought using the code that you were getting me to try would ask for the title bar string, now if the Folder options setting for 'Display full title path in title bar' is checked then the full path will be displayed in the title bar, if not only the folder name will be, I was wondering whether this could present a problem. that's all.

Thanks in advance
Jason
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Okay, no, the title bar should not be a problem. Can you wait til the weekend? I've not much time right now...

Regards, Madshi.
0
 
LVL 20

Accepted Solution

by:
Madshi earned 400 total points
Comment Utility
Here comes the code. It's a bit ugly, because WinExec/ShellExecute/CreateProcess returns before the explorer window is opened. Even waiting with "WaitForInputIdle" returns before the window is opened. So I found no other solution than poll for that window for 2 seconds. Ugly, but it works...

Regards, Madshi.

type
  TEnumWindowsRec = record
    pid  : dword;
    list : TList;
  end;

function EnumWindowsProc(window: cardinal; var ewr: TEnumWindowsRec) : bool; stdcall;
var pid : dword;
begin
  result := true;
  GetWindowThreadProcessID(window, @pid);
  if (pid = ewr.pid) and
     (GetParent(window) = 0) and
     (GetWindow(window, GW_OWNER) = 0) and
     IsWindowVisible(window) and
     (GetWindowLong(window, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0) and
     (ewr.list.IndexOf(pointer(window)) = -1) then
    ewr.list.Add(pointer(window));
end;

function StartExplorer : dword;
var ewr1, ewr2 : TEnumWindowsRec;
    i1         : integer;
    time       : dword;
begin
  GetWindowThreadProcessID(windows.FindWindow('Shell_TrayWnd', ''), @ewr1.pid);
  ewr1.list := TList.Create;
  EnumWindows(@EnumWindowsProc, integer(@ewr1));
  WinExec('explorer.exe', SW_SHOWNORMAL);
  time := GetTickCount;
  ewr2.pid  := ewr1.pid;
  ewr2.list := TList.Create;
  repeat
    EnumWindows(@EnumWindowsProc, integer(@ewr2));
    result := 0;
    for i1 := 0 to ewr2.list.Count - 1 do
      if ewr1.list.IndexOf(ewr2.list.Items[i1]) = -1 then
        result := dword(ewr2.list.Items[i1]);
    if result = 0 then
      Sleep(50);
  until (result <> 0) or (GetTickCount - time > 2000);
  ewr1.list.Free;
  ewr2.list.Free;
end;

initialization
  ShowWindow(StartExplorer, SW_MINIMIZE);
  ExitProcess(0);
end.
0
 

Author Comment

by:JasonC
Comment Utility
Looks good, however, how do i tell the explorer window that is displayed what directory to display, that was the whole idea of this. This looks as though it will display an explorer window. But without telling it what folder to display, what would be the point.
0
 

Author Comment

by:JasonC
Comment Utility
Also the two second wait, would this also work on a 486 or even 386, obviously I am not going to run on one of them, but someone might, is the 2 second wait just enough time for say your computer, or is this a set time that is needed for windows?
0
 

Author Comment

by:JasonC
Comment Utility
Also the two second wait, would this also work on a 486 or even 386, obviously I am not going to run on one of them, but someone might, is the 2 second wait just enough time for say your computer, or is this a set time that is needed for windows?
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
To start the explorer with a specific start path, simply do this:

WinExec('explorer.exe c:\wantedPath', SW_SHOWNORMAL);

The 2 seconds was just a guessed time. If you want to run your program on a 486, too, you should perhaps increase this time. Well, I don't know - perhaps sometimes there comes no explorer window? You should try that. If the explorer window comes ALWAYS, then you can wait infinitely, or at least much longer than 2 seconds.
0
 

Author Comment

by:JasonC
Comment Utility
Great, it works perfectly, when I sent the handle to my resize code it works brilliantly. I adjusted the wait time to 9 seconds, so hopefully that  should long enough for the slowest machine that will use the program. Below is the code I use to adjust the size of the explorer window and position. If anyone reading this wants that info as well.

ExplorerSize := 1;  //FullScreen
ExplorerSize := 2;  //Half Screen
ExplorerSize := 3;  //Third Screen
ExplorerAlignment := 1;  //Vertical
ExplorerAlignment := 2;  //Horizontal
ExplorerPosition := 1;  //If vertical left, if horizontal top
ExplorerPosition := 2;  //If vertical right, if horizontal bottom

I just like making some things automated for my users if they want the option!

function SetExplorerPosition(MyHan : THandle; Redraw : Boolean) : THandle;
var
  DTLeft, DTRight, DTTop, DTBottom: Integer;
  AppBarInfo: TAppBarData;
begin
  //  MyHan := 0;
  AppBarInfo.cbSize := SizeOf(TAppBarData);
  AppBarInfo.hWnd := MyHan;
  SHAppBarMessage(ABM_GETTASKBARPOS, AppBarInfo);
  with AppBarInfo.rc do
  begin
    if (Left = -2) and (Top = -2) and (Bottom - Top > Right - Left) then
      DTLeft := Right
    else
      DTLeft := 0;
    if (Top = -2) and (Left = -2) and (Right - Left > Bottom - Top) then
      DTTop := Bottom
    else
      DTTop := 0;
    if (Right = Screen.Width + 2) and (Top = -2) and (Bottom - Top > Right - Left) then
      DTRight := Left
    else
      DTRight := Screen.Width;
    if (Left = -2) and (Bottom = Screen.Height + 2) and (Right - Left > Bottom - Top) then
      DTBottom := Top
    else
      DTBottom := Screen.Height;
  end;
  if ExplorerSize = 2 then
  begin
    if ExplorerAlignment = 1 then
    begin
      if ExplorerPosition = 1 then //Help on Left Half
        DTRight := Screen.Width div 2
      else
      //Help on Right Half
        DTLeft := Screen.Width div 2;
    end
    else
      if ExplorerAlignment = 2 then
      begin
        if ExplorerPosition = 1 then //Help on Top Half
          DTBottom := Screen.Height div 2
        else
        begin //Help on Bottom Half
          DTTop := Screen.Height div 2;
          DTBottom := DTBottom - (Screen.Height div 2);
        end;
      end
  end
  else
    if ExplorerSize = 3 then
    begin
      if ExplorerAlignment = 1 then
      begin
        if ExplorerPosition = 1 then //Help on Left Half
          DTRight := Screen.Width div 3
        else
        //Help on Right Half
          DTLeft := (Screen.Width div 3) * 2;
      end
      else
        if ExplorerAlignment = 2 then
        begin
          if ExplorerPosition = 1 then //Help on Top Half
            DTBottom := Screen.Height div 3
          else
          begin //Help on Bottom Half
            DTTop := (Screen.Height div 3) * 2;
            DTBottom := DTBottom - ((Screen.Height div 3) * 2);
          end;
        end
    end;
  //  MyHan := FindWindow('',Pchar(MyContact.CompanyName));
  MoveWindow(MyHan, DTLeft, DTTop, DTRight, DTBottom, Redraw);
  if MyHan <> 0 then
    Result := MyHan
  else
    Result := 0;
end;


Great work and thanks again Madshi!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 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

16 Experts available now in Live!

Get 1:1 Help Now