Windows 11 doesn't show proper name for notepad windows

Started by pguild, April 27, 2023, 08:18:43 PM

Previous topic - Next topic

pguild

Windows 11 makes me want to %^&*)!  >:(
My program prepares to open a notepad window called, say, "Temp.txt". And the program tries to check to see if that window is already open. In Windows 10, the notepad window would contain the name of the file as in "Temp.txt".  But with Windows 11 the name of the window is just "Notepad" so I can't tell if the window is already open. So my program opens multiple copies of the window, which sometimes causes a serious issue.

At least I got Windows to stop throwing all notepad windows into one window with tabs. (By tweaking settings.)

Any workaround for this fiasco?
www.DogTrainingPsychology.com -- "Don't wish it were easier, wish you were better."  as aphorism by Jim Rohn as quoted in the Kindle Book, GEMS OF WISDOM by Philip Seyer

td

If you simply want to detect whether or not "Notepad" is already running, try the AppExist function. In fact, there is an example using "Notepad.exe" in the function's documentation.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

pguild

Let me try to be clear.  I want to see if Notepad is open with a particular text file.  For example, I might have 3 notepad windows open, each with a different text file. For example: ABC.txt  DEF.txt and GHI.txt  In Windows 10,  if I asked my program to open DEF.txt it could throw up a message: "This window is already open.," and then it would activate the window.  Additionally, my program could tell whether it had been saved or not.    Now in Windows 11, my program fails to detect the existence of DEF.txt and opens another copy causing confusion and potential loss of data if I edit and save the wrong version. Also, in Windows 11 I cannot position the Window or set it to always on top.  Windows 11 is a disaster.   >:( :(
\

www.DogTrainingPsychology.com -- "Don't wish it were easier, wish you were better."  as aphorism by Jim Rohn as quoted in the Kindle Book, GEMS OF WISDOM by Philip Seyer

ChuckC

On Windows 11, the traditional "notepad.exe", which was a Win32 Desktop application, has been re-implemented as a fully-trusted UWP app with a location under "C:\Program Files\WindowsApps\".  One of the defining features of Notepad as a UWP app is that it now has a tabbed interface just like the Windows File Explorer windows have on Windows 11 after the Fall 2022 [e.g. 22H2] feature update was applied.

What you are now observing is that the main window title for Notepad remains constant while the names of the individual tabs change based on the name of the file that is open in each tab.

It will be necessary for you to change your methodology to account for this.

td

Quote from: pguild on April 28, 2023, 01:14:58 PM
Let me try to be clear.  I want to see if Notepad is open with a particular text file.  For example, I might have 3 notepad windows open, each with a different text file. For example: ABC.txt  DEF.txt and GHI.txt  In Windows 10,  if I asked my program to open DEF.txt it could throw up a message: "This window is already open.," and then it would activate the window.  Additionally, my program could tell whether it had been saved or not.    Now in Windows 11, my program fails to detect the existence of DEF.txt and opens another copy causing confusion and potential loss of data if I edit and save the wrong version. Also, in Windows 11 I cannot position the Window or set it to always on top.  Windows 11 is a disaster.   >:( :(
\

I have no problems positioning a Notepad.exe main window with WinPlace if that is what you are talking about. That is because Notepad.exe's window name is "Notepad".
Querying for open tab names is another subject and would require a little more work to figure out. As Chuck suggested you will need a different approach. There are a few possibilities but they require some trial and error to confirm usability.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

To continue down the path that Tony hinted at, as always, the 1st choice is the Control Manager Extender.  However, with so much of what Microsoft has done with replacing the legacy "Common Controls" with newer forms of UI widgets & gadgets, etc., sometimes that isn't a viable option.  Given the nature of what UWP apps are, it's likely that you'll have to use Microsoft's automation classes in .NET to properly interrogate an instance of the UWP form of Notepad to query it for its open tabs and their respective names.

td

The new vector graphics-based UI is still based on the same underlying Windows GUI system. It is just dumbed down by a layer or two of abstraction. The Control Manager extender has functions that allow the navigation of a top-level window's child window class structure to find a specific window.  Since the "new" UI still has window class names, finding a targeted window by class and then by name is possible. When I get the chance I will post a hopefully working example.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: ChuckC on April 28, 2023, 06:00:27 PM
it's likely that you'll have to use Microsoft's automation classes in .NET to properly interrogate an instance of the UWP form of Notepad to query it for its open tabs and their respective names.


Curious, what are some of these classes. I see there is a windows Power Automate [with pricing] but don't see that applying here.

td

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on April 29, 2023, 06:49:59 AM
The namespace is "System.Windows.Automation" which is part of the dotNet Framework.


Yeah, but a little complicated for the Op's ask. Need kind of a



Foreach tab in [notepad].tabs
        Message("",tab.title)
End



which, of course, aint gonna happen >:(


td

Sometimes stuff isn't easy but it can be an opportunity to learn. As I mentioned several posts back, I will try to help the OP when time permits.

FWIW, it is possible to iterate through the "tabs" using the Control Manager Extender to obtain the content of each tab but the tab names are not accessible.  Whether dotNet can do any better is yet to be determined.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on April 29, 2023, 04:53:28 PM
Sometimes stuff isn't easy but it can be an opportunity to learn.



Correct. But you must admit that all of the latest UWP, WinRT, XAML acronyms going around related to 'the future of Windows' some of us non-programming minions get a little confused. I'm facing scripts I compiled  from 2007-2012 using the ACE.OLEDB.12 see that users have moved to 64-bit Office, and [of course] as it turns out, just changing to ACE.OLEDB.16 is no cure.


To be honest, with the wealth of knowledge and experience you and others like Chuck have with the 'innerds' of Windows. I would love to see a WB webex series of 'ask the experts'.  And I realize time zones are an issue, and maybe use of your time... that is why I would contribute $$$ for a useful session, and maybe others reading this would feel the same.




ChuckC

Google is your friend.  It's certainly my friend, and I lean on that friend a lot when researching things.

learn.microsoft.com is where all of the Win32 API, .NET and Driver Development Kit [DDK] stuff resides these days.  Well formed Google searches will frequently lead you there.

There is a lot of formerly "proprietary" stuff that Microsoft has made publicly available on github.com under various projects/repos.  Again, Google helps you find it.

It's a never ending task with continuing to learn & self-educate along the lines "we've got to keep running faster & faster just the keep up with staying in place".

If you're a person who learns well from a printed book, I strongly recommend "Windows Internals, 7th Edition, Parts 1 & 2".  It's not going to present you with code samples, but it's fantastic if you want to know the "how" & "why" of what Windows does at low levels.  Take that foundation and build on it.  It's not "light reading", but what's in those 2 books will certainly provide you with a road map of what you need to investigate in further detail.

As for Microsoft's application automation stuff, look at the online docs for those .NET classes.  Then, do some searches for code examples outside of Microsoft's site(s).  Great places to find examples and questions about specific use cases are on codeproject.com and stackexchange.com.  Less frequently, reddit will turn up with something.  There are also interesting projects on github.com that may turn up useful information.

td

It doesn't get much easier than this. A cut-and-paste of Kirby's Chrome browser tab script with minor modifications.  Note that this is just a functional example for the OP to use in developing his own script. The intention is not that it is "the" solution.

Code (winbatch) Select
;; Start Notepad with a file loaded.
Run("Notepad.exe", DirScript():"NotepadExample.txt") ;; Put your existing file name here.
Terminate(!WinWaitExist("Notepad",30), "Notepad Tab Example", "Notepad does not exist")

; Load required assemblies.
ObjectClrOption("useany","UIAutomationClient")
ObjectClrOption("useany","UIAutomationTypes")
ObjectClrOption("useany","System")
 
; Search scope enumerated values.
enumScope  =  ObjectClrNew("System.Windows.Automation.TreeScope")
 
;  Get access to the desktop window which is the parent of all other windows.
objUiElement = ObjectClrNew("System.Windows.Automation.AutomationElement")
objUiRoot = objUiElement.RootElement
 
; Instantiate a class-name property condition for Notpad.
objPropCon1 =  ObjectClrNew("System.Windows.Automation.PropertyCondition", objUiElement.ClassNameProperty, "Notepad")
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Find a Notepad window under the desktop
 
; set scope to "children"
nElement  = enumScope.Children
Scope = ObjectClrType("System.Windows.Automation.TreeScope",nElement)
 
; Find all of those under the desktop.
objNotepadArr = objUiRoot.FindAll(Scope,objPropCon1)
 
; for each one...
ForEach objNotepad In objNotepadArr
 
    ; get the main window title
    maintitle = objNotepad.GetCurrentPropertyValue(objUiElement.NameProperty)
 
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Find the all the tabitem type controls in Notepad
 
    ; This is the "types" of controls
    ConType = ObjectClrNew("System.Windows.Automation.ControlType")
 
    ; This is a "condition"  Note that the app developer sets the type so some trial and error
    ; might be required to get the correct condition.
    searchCon =  ObjectClrNew("System.Windows.Automation.PropertyCondition", objUiElement.ControlTypeProperty, ConType.TabItem);
 
    ; This is a "scope"
    nElement  = enumScope.Descendants
    Scope = ObjectClrType("System.Windows.Automation.TreeScope",nElement)
 
    ; Find those windows.
    objArr = objNotepad.FindAll(Scope,searchCon)
 
    lis = "Main Window title = """:maintitle:"""":@lf:@lf
    ii = 0
    ForEach item In objArr
      x = item.GetCurrentPropertyValue(objUiElement.NameProperty)
      ii = ii + 1
      lis = ItemInsert(ii:": ":x, -1, lis, @lf)
    Next
 
    Message("Notpad tabs",lis)
  Next
 
Exit


Since it is a cut-and-paste didn't even have to think too hard...
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Quote from: ChuckC on April 30, 2023, 06:48:01 PM
Google is your friend.  It's certainly my friend, and I lean on that friend a lot when researching things.

learn.microsoft.com is where all of the Win32 API, .NET and Driver Development Kit [DDK] stuff resides these days.  Well formed Google searches will frequently lead you there.

There is a lot of formerly "proprietary" stuff that Microsoft has made publicly available on github.com under various projects/repos.  Again, Google helps you find it.

It's a never ending task with continuing to learn & self-educate along the lines "we've got to keep running faster & faster just the keep up with staying in place".

If you're a person who learns well from a printed book, I strongly recommend "Windows Internals, 7th Edition, Parts 1 & 2".  It's not going to present you with code samples, but it's fantastic if you want to know the "how" & "why" of what Windows does at low levels.  Take that foundation and build on it.  It's not "light reading", but what's in those 2 books will certainly provide you with a road map of what you need to investigate in further detail.

As for Microsoft's application automation stuff, look at the online docs for those .NET classes.  Then, do some searches for code examples outside of Microsoft's site(s).  Great places to find examples and questions about specific use cases are on codeproject.com and stackexchange.com.  Less frequently, reddit will turn up with something.  There are also interesting projects on github.com that may turn up useful information.

Very sound advice. The only thing I would add is a caution. Don't be beguiled by the Tech Industry's next-big-thing and new-and-improved marketing hype. Think for yourself.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

pguild

Ha,  8) that new feature in Windows 11 is sick and a troublemaker, in my not-so-humble opinion.  >:(  But we don't have to accept the multiple tabs feature of the new, but trouble-making notepad. I don't and won't.  Here is what Google's Bard says ( via bard.google.com ) :

To disable the new tabs feature for Notepad in Windows 11, you can use the following steps:

Open Notepad.
Click on the "File" menu.
Click on "Settings".
Under the "General" tab, uncheck the box next to "Enable tabs".
Click on "OK".
Note that after disabling tabs, you will no longer be able to open multiple files in a single Notepad window.
If you want to open multiple files, you will need to open them in separate Notepad windows.

I still can't easily grab the name of the Window such that it matches the file being edited.  However, I know the name of the file because my program opened it from the disk like this:

shellexecute( NotePadFilename, "", "", @NORMAL, "" ) ;open it from disk

Every window has an internal ID that you can use to manipulate that window. So multiple notepad windows can be open, all named 'Notepad", but each one deals with a different filename; the good news is that each one will have a different winid.

After opening a notepad file from the disk, I grab the ID of the window like this:

        Timedelay(1)
        win = wingetactive()
        winid = winidget(win)

Next, I store the filename and the winid as a list in a control file of my own.
Before opening a notepad file from the disk, I see if I have a winid stored for it, showing that it might be open already.
Why because I don't want duplicate copies of the same filename open for editing at once.

I check to see if a window already exists using:

      WinFound = WinExist(OpenWinID) && OpenWinID > ""

Note that an empty winid counts as a notepad that is active, so I check to make sure that the OpenWinID variable has some value in it.

If I find a winid associated with a file name, I activate it using its winid.

      winactivate(OpenWinID)

Note that if a Notepad window is closed its winid will still be in my control file, so when I find that the winid does not exist, I update the control file and remove the record of the file name and win id.

Note also: not all details are shown here. Just my general approach.
www.DogTrainingPsychology.com -- "Don't wish it were easier, wish you were better."  as aphorism by Jim Rohn as quoted in the Kindle Book, GEMS OF WISDOM by Philip Seyer

kdmoyers

clever to turn off the "feature"!

Also, I've had good luck in the past with RunShell using the @GETPROCID option in cases like this where I need to track the process.  Doesn't always work though -- some processes seem to shift around and it does not track so well.
The mind is everything; What you think, you become.

ChuckC

Quote from: kdmoyers on May 04, 2023, 05:11:49 AM
-- some processes seem to shift around and it does not track so well.

This is something that happens quite often with things like software installer packages where they initially launch running "restricted" and then later create a child process that gets elevated via UAC to then go on and perform the actual installation operations.

td

The shifting bit is one of the reasons why the AppProcID function was added to WIL last year.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade