How can I uniquely identify a monitor? - c#

I am trying to write a program for re-configuring displays in the cases where a display loses connection, and Windows is not able to correctly reconfigure its prior settings.
Usually if you unplug a monitor, Windows seems to keep track of configuration settings for the display. Example, I have three monitors hooked up right now. If I unplug my "main display", Windows will make one of the remaining two monitors the main display. Then if I reconnect the monitor, Windows will usually remember the configuration for that monitor, specifically in this case that it was my main display, and set it appropriately.
I am currently using EnumDisplayDevices, EnumDisplaySettings, and ChangeDisplaySettingsEx to set the configurations for each monitor (resolution, orientation, etc). However, looking at what information EnumDisplayDevices and EnumDisplaySettings populate the DISPLAY_DEVICE and DEVMODE structs with, nothing seems to be able to uniquely identify the monitors themselves. I'll get values that will uniquely identify each display from each other for the current configuration (\.\DISPLAY1 and \.\DISPLAY2 \.\DISPLAY3, for example), but if I unplug the monitor that had the identifier \.\DISPLAY1, next time running I'll get the values \.\DISPLAY1 and \.\DISPLAY2. So that value can't be used to unqiuely identify a specific monitor later on.
Is there some piece of unique information about each monitor hooked up that I can use to identify them? My feeling that such a piece of information might exist comes from the fact that most of the time if I unplug a monitor and plug it back in, Windows will retain its configuration.

The wmimonitorid class accesses more H/W specific data than EnumDisplaySettings, in particular, the SerialNumberID which should be unique (at the very least) to the entire range of monitors from a specific mfg.
The field is a Uint16 array, so can be read in with code similar to that provided in this answer.
Also try DeviceID in the Win32-PNPEntity class, for PnP monitors. Can be retrieved in a WMI query based on pseudo code like:
SELECT * FROM Win32_PnPEntity WHERE ClassGuid={4d36e96e-e325-11ce-bfc1-08002be10318}

Related

How to let cable unplugging/re-plugging not affect the screen numbers in the program

This might be a silly question, but I could not find any information on this. Is there any way to display a specific form to a specific monitor?
I am making a WinForm application in C#, I need to make it not affected by the HDMI cable's disconnection and re-connection. I have 3 forms (A, B, and C), and Form A needs to be always displayed on monitorA, Form B on monitorB, and Form C on monitorC. I am currently assigning each form on each monitor like
FormA.Location = Screen.AllScreens[0].WorkingArea.Location; //screen 0 = monitor A
FormB.Location = Screen.AllScreens[1].WorkingArea.Location; //screen 1 = monitor B
FormC.Location = Screen.AllScreens[2].WorkingArea.Location; //screen 2 = monitor C
This works fine until I disconnect the cable(s) and reconnect them. Sometimes, it doesn't affect the program, but sometimes, disconnecting and re-connecting the cables changes the screen number assigned to each monitor, and messes up the screen configuration. Like Form A is displayed on monitorC.
It seems like the screen number is assigned on the hardware side, but is there any way to fix the monitor-form relationship? Thank you for your help.
I'm afraid that is something that Windows does and isn't easily avoided. If you have an nVidia Pro graphics adapter, or another adapter that supports it, you can setup the graphics driver to load monitor EDID from a file instead of from the monitor and lock Windows into thinking the monitor is permanently connected. There may be other brands that support disabling monitor detection as well.

how to show some info on secondary monitor in C# WPF?

i have some info that store in DB that should be displays some info about path destination and buses on secondary monitors in passenger terminal waiting rooms
now how can i doing this in c# wpf application?
does it need to design any form and than reflect to monitors or it could be done programmatically? or another way...
i am beginner in this scenario
You can split your application in two executables: The first one to insert data in the database. The second one to display info in secundary monitor, reading the information saved on the database.
The two application can run on same machine or separeted ones. If you can use a dedicated machine you can just run you second app on startup and then send computer output to secundary monitor.
If you need to run then on same machine you should have two videocard on that computer and use them as extended displays. The find a way to send specific app to specific screen. Hope it helps you.

c# read syslistview32 items tooltips via winapi

i want to write an application, which reads under windows xp the quick launch items in the order like they are located in the taskbar,
and sets hotkeys for each of these item.
windows + 1 should start the first application
windows + 2 the second, etc.
(like in windows 7)
all of these items are found i a folder, but if i read the items of this folder, i dont get the right order of these items.
i found two solutions the get the right order - first:
in the registry an entry is found, where its saved how they are located, but not in plain text. i dont know how to read this, and cant reverse engine it.
the second:
read via winapi the items tooltip from the taskbar, so i can (if there are not items with the same name) search via the name in the quick launch folder.
the quick launch bar is just a listview (syslistview32).
via sendmessage i got it work to count the items, and start one (faking a click on this item), but how the hell can i read the tooltip?
i have googled a lot, tried everything, but i didnt get it run.
i hope you have any snippets for me, to solve this problem.
cheers
Determining the order of the items in the Quick Launch toolbar programmatically is going to be inherently fragile. There's not an API exposed for this, which means that it's subject to change in future versions of Windows, breaking your code that relied on assumptions about undocumented implementation details.
However, this is less of a problem in this specific case than it normally would be, since the Quick Launch toolbar doesn't exist anymore (or, at least, no one uses it anymore). The last version of Windows that used the Quick Launch toolbar was Vista, so if you make sure that your code is compatible with Vista and earlier, you should be fine. It won't work with newer versions anyway.
The positions of items in the Quick Launch toolbar is stored in the Registry in the following key:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop
You can extract the information from there, parse and interpret it, and then use it as you like. As you mention, this information isn't stored in plain text form because that would be very slow for the shell to load and parse itself. Since this is undocumented and not designed to be used by clients, they had no particular benefit in making it user (or developer) friendly. All that matters is what's most efficient for the shell, and storing the binary information from its internal structures is the obvious choice.
You will need to reverse engineer this in order for it to be useful to you. The way I'd go about it is probably by setting up a test environment with a couple of items in the Quick Launch bar in a particular order, exporting the information from the Registry, moving one of the items around, exporting the updated information from the Registry, and comparing the two exported Registry files to see what changed. Rinse and repeat as many times as necessary to deduce the pattern. (Really makes you wonder why so many developers actually do take the time to reverse-engineer undocumented aspects of Windows, doesn't it?)
The other option would be to use Spy++ to investigate the windows that implement the taskbar and its Quick Launch toolbar. I don't have a pre-Windows 7 system around, but it sounds like from the question that you've already done this and determined that the Quick Launch toolbar is implemented using a standard ListView. If you know the name of that window (and the names of its ancestor windows), you can walk through those windows to obtain a handle to the window you're interested in. And then you can determine the order of the items in the window as if it were a standard ListView in your own application.
The documentation for ListView controls is here; that should get you started in the right direction. You can get the text of one of the subitems by sending the LVM_GETITEMTEXT message.
This is probably the easier way of doing it. The same caveats apply--there is nothing keeping future versions of Windows from changing the names of those windows or the way that the taskbar is implemented, but since the only versions of Windows that have a Quick Launch toolbar have already been released (and therefore aren't likely to change), this may not be a big problem.
Then again, with the fact of the Quick Launch toolbar's obsolescence in mind, I struggle to comprehend why this endeavor is even worthy of investing developer time.
Also, even once you get this program all written and installed, consider what happens when the user adds a new item to the Quick Launch toolbar or re-arranges the existing items. How is your utility going to know that and adjust the keyboard shortcuts accordingly? What if an installer adds/removes an item from the Quick Launch toolbar?

A service that would track and catch whenever someone is trying to take a screenshot

Is it possible to write a service program that would catch an event of someone trying to take a screen capture? Not that of pressing a printscreen button or any other key combination, though, but of the event itself, even if it is done by some external tool?
You can't realistically, because anyone could write a simple application that can take a screenshot.
The command being, GetDC(NULL) (msdn GetDC).
Hooking this function also wouldn't work since apps can make use of this for legitimate reasons so you'd have to try and filter out false positives.
Also, you've only prevented one class of problem, what if the user emails the file to someone? What if the user copies the text rather than uses a screen shot? What if the user takes a photo using their mobile phone?
If you have sensitive information that must be protected the only real option is to educate users and/or restrict their access. E.g. machines with sensitive information are not connected to a public network, USB drives are disabled and user's are not allowed to bring anything with a camera or data storage near the machines.
If it's just to avoid silly mistakes, then you could hook the keyboard and look for the print screen key. This however will not detect applications (such as Snipping Tool).
This could be done via a clentscript and using AJAX to send a message back to your servers, however you cannot guarantee the user wont have javascript turned off, or the user gets around this by running through a proxy or vm environment.
In short you could do this but there is no way to 100% guarantee its effectiveness.

How to detect when screen brightness or system volume changed?

I want to detect when either of these changes and display an overlay on screen showing the current level. If there is a tool for this, then please point me to it. But if not how would I programatically get this (C#)?
The WmiMonitorBrightness class might be what you're looking for. You'll probably need to periodically query it to get changes.
If you talking about the softwares especially for laptops which OEMs like Dell/IBM etc give along with the windows installation to indicate brightness/voulme etc change then try this approach.
Install global message hooks and see what message is posted when volume/brightness buttons are clicked. You can use spy++ to detect the value of the message. In my opinion each vendor would have a different code for the buttons which are generally used along with the Function(Fn) key. Once you know the messages, make an application which installs a global hook for the system and display the animation or level bar as per your requirement.
The WmiMonitorBrightness class is supported for vista and above so if you using Win XP then it might not help you.

Categories