Change dwm colorization - Windows 7 - vb.net

I'm currently trying to write a program in VB.NET which fluidly changes the DWM window colorization colors in Windows 7.
I first tried to edit Registry values directly, but I had to restart the UXSMS service. This solution was unsatisfying, because of the toggle of the taskbar.
I'm now searching for a function in a DLL such as user32.dll or themecpl.dll which can reproduce the behaviour of control panel when setting the window color.
I'm now on IDA, searching for the adquate function (CColorCplPage::SetDwmColorizationColor seems good!). If anyone has one, please share it!
(If anyone need screens or code, please ask. Sorry for my poor English.)

Your first attempt failed because manually editing the Registry is never the correct way to change system settings. As you found out, lots of Windows components (and other applications!) read those configuration values once and cache them, preventing your changes from being propagated. Another problem (and you'd be surprised how often I see this) is applications that attempt to muck around in the Registry generally end up corrupting things.
Instead, you should call the documented API to change the settings. There's almost always a documented way of doing this, and if there isn't, well then you shouldn't be doing it.
This appears to be one of those cases. There's a documented DwmGetColorizationColor function, but there's no corresponding DwmSetColorizationColor function, as one might expect.
The reason is that the user is supposed to be the only one who can change their colorization settings, not other applications. You might promise not to abuse this, and to only make such changes at the user's explicit request, but not all applications can be trusted to do this. Lots of people would use it maliciously, so these functions have not been documented and exposed.
But as usual, if you press on, you can usually find an undocumented way of doing things. The problem with using undocumented functions is that there's no guarantee they'll work or continue to work. They've been intentionally left undocumented because they're liable to change on new versions of Windows. You should only use them at your own risk.
In this case, if you use a program like DumpBin to obtain a list of all the exported functions from the DWM DLL (dwmapi.dll), you'll see a number of undocumented exported functions.
The ones you're interested in are DwmGetColorizationParameters and DwmSetColorizationParameters. Both of these functions take a COLORIZATIONPARAMS structure as an argument that contains the values they need.
So, you need to reverse engineer these functions and obtain the appropriate definitions. Then, you can call the DwmGetColorizationParameters function, passing in a COLORIZATIONPARAMS structure to obtain the current configuration settings; modify the member of the structure that contains the current colorization color; and then pass that modified version of the structure to the DwmSetColorizationParameters function.
Did I mention that I don't recommend doing this?

Related

Can FsXaml be used in an F# interpreted script?

I just converted one of the FsXaml demo programs to an interpreted F# script so I could experiment with it and learn. It wouldn't run, and the interpreter gave me the following error message:
System.NotSupportedException: The invoked member is not supported in a
dynamic assembly.
at System.Reflection.Emit.InternalAssemblyBuilder.GetManifestResourceStream(String
name)
at FsXaml.InjectXaml.from(String file, Object root)
at
FsXaml.App.InitializeComponent() at FsXaml.App..ctor()
at
FSI_0002.main[a](a argv)
in C:\Users\bobmc\OneDrive\FSharp\Learning\WPFExamples\FsXaml\demos\WpfSimpleMvvmApplication\WPFApp.fsx:line 104
at .$FSI_0002.main#() in
C:\Users\bobmc\OneDrive\FSharp\Learning\WPFExamples\FsXaml\demos\WpfSimpleMvvmApplication\WPFApp.fsx:line
109
Can I use the F# interpreter with FsXaml? Thanks to all for your help.
Unfortunately, WPF and scripts don't play well together.
The exception occurs within the WPF runtime itself - FsXaml.InjectXaml is using a XamlObjectWriter to populate the type with the contents from the XAML file. This type doesn't work if you're using a dynamic assembly (like FSI), which unfortunately means that FsXaml will likely never be able to work from FSI.
That being said, even if there was a way around this, it'd be of very limited use. WPF also has restrictions that make it not play well with a scripting scenario, such as the "only one application can ever be created within a given AppDomain" restriction. That one makes it so closing the "main" (first) window makes it so you can never open another one. As such, I haven't prioritized trying to make this work in FSI.
I'd be happy to accept contributions if somebody has an idea of how to make FsXaml play more nicely within the context of FSI, but at this point, I don't see a good solution for that usage scenario.
Edit: FsXaml 3.1.6 now includes functionality to make this a lot easier. It works well, provided you don't close the main window, or you use dialogs. There is a demo application/script illustrating this.

passing options to a matplotlib backend in a clean way

For my personal use, several times I have modified the matplotlib gtk backend (also the tk and wx) , replacing the window with a notebook. This is because I use too many plots at the same time.
This time around I feel I can take the challenge to do a pull-request for my changes. But I want to do it as clean as possible. That is where I need advice (clean is the key).
I would like to place my class TabbedFigureManagerGTK3 inside
backend_gtk3.py
The problem is that using
matplotlib.use('gtk3cairo')
or
matplotlib.use('gtk3agg')
Directs the specified backend (gtk3cairo or gtk3agg) to use backend_gtk3.FigureManagerGTK3
I do not want to replicate backend_gtk3agg.py and backend_gtk3cairo.py just to change the call to backend_gtk3.FigureManagerGTK3
I would like to implement a solution that allows the user to pass an option to the backend, and from there it choses the traditional FigureManagerGTK3 or my TabbedFigureManagerGTK3
I am looking for a recomendation on how to do it that has more chances to be accepted upstream (after pull-request and the whole shebang).
Do I modify matplotlib.use to add something like **kwargs?
Do I just recreate the whole backend_gtk3agg.py and backend_gtk3cairo.py (subclassing of course)
Do I forget about trying to get this accepted and do it breaking the Coding guide
Thanks
Federico
This does sound like a nifty feature.
I would do it by modifying the existing manager and following how the PySide vs PyQt issue is handled (by using a secondary rcParams which controls which one the backend imports). In your case, I would add backend.gtk3.tabbed, or something similarly named, which controls how the manager behaves.
Write your modifications so that changes as little of the existing api as possible (breaking backwards compatibility is a no-go) and make it so a user that doesn't explicitly enable your changes won't even know they are there.
Also email the dev list, they are all pretty friendly. Or just open a PR, that is the most effective way to get feed back.

Is there an easy way to determine which parts of a vb.net project is still used?

I maintain an old vb.net project that I didn't make and I was wondering if there's an easy way to determine which parts of the software is still used today by the staff where I work.
I would like to log all function calls without having to edit each one of them if possible.
The project has 27 forms and 6 modules.
Any ideas?
Thanks!
There is no way to 100% determine everything that is used by the system. Vb.Net supports dynamic invocation of methods / properties. Hence you can't even do tricks like delete some code and see if it recompiles. Even if it compiles it could be invoked dynamically.
One way to get a sense of what code is used is to profile the application. Start up the profiler, run the app and go through all of the ways in which the app is used. The resulting profile should give you a good sense of what parts are used. It's very possible though this approach will miss code though

how to sync the Culture of microsoft.visualbasic.compatibility.vb6.format with the application.currentCulture?

Context: a program written in VB.NET, developed/maintained in VisualStudio2012, targeting framework v3.5.
A few years ago, the program was in VB(6) and we "translated" it to VB.NET. As a result of the transformation, which was mostly automated, we still have quite a few places in the code where formatting of doubles (and dates/...) for textual presentation is processed as in:
Dim sValue As String = Microsoft.VisualBasic.Compatibility.VB6.Format(dblValue, "0.00")
Conversely, when we need to extract a Double value from such a string, we use
Dim dblValue As Double = CDbl(sValue)
CDbl "listens to" the System.Globalization.CultureInfo.CurrentCulture of the applications Thread, and this does NOT change when - during the run of the code - you change the Regional Settings through the Control Panel.
However, the VB6.Format as executed in the code starts out conforming to the currentCulture of the application (as you might expect), BUT apparently (I didn't know this, but accidentally found out) listens to CHANGES in the Regional Settings and responds immediately to any changes you make there during the program execution. This implies that the CDbl() and VB6.Format() become mutually inconsistent.
Of course, changing the Regional Settings during program execution is awkward, and moreover, if you wish to support it, you can manage it by catching the SystemEvents.UserPreferenceChanged (and -Changing) events and act upon their occurrences.
However, the "different behaviour" of VB6.FORMAT versus "normal" casts as CDbl(someString) regarding changes in the Culture/Regional Settings, strikes me as undesirable. Preferably you would have VB6.Format to comply ALWAYS with the application/thread-CurrentCulture, and you may THEN choose how you want your code to respond to userpreference changes. Furthermore, I'd like to gain some more insight in the issue.
My question, therefore, is:
Is there a way to compile/arrange/... things such that the (Microsoft.VisualBasic.Compatibility.)VB6.Format listens to the application-CurrentCulture and NOT respond - without "our consent" - to changes in Regional Settings?
Additional information:
The program is compiled with - for the visualbasic stuff - a reference in the project (VisualStudio2012) to:
C:\Windows\Microsoft.Net\Framework\V2.0.50727\Microsoft.VisualBasic.Compatibility.dll (and ...Data.dll).
Any "educational" information or suggestion is welcome. The issue is not causing any real problems in our program, but I feel that we should/might have a better understanding and maybe even methods to make things more robust.
The VB6 Format() function is actually an operating system function under the hood. VarFormat(), a function exported by oleaut32.dll. Backgrounder answer is here. The MSDN library article is here.
As you can tell from the MSDN article, the function doesn't permit specifying a culture or culture specific settings, other than the day-of-week rules. This function dates from 1996, life was much simpler back then. So what you see is now easy to explain, it cannot know anything about the .NET Thread.CurrentCulture setting.

How to access the variable to which OS copies

An interesting feature, I have seen in jDownloader software is any links I copy in the browser window (i.e., Ctrl+c), the copied content links automatically appears ( i.e., with out me actually pasting it) in their UI and starts downloading the content from the links, if they are valid.
I would like to program the same but am puzzled as how to access the variable to which OS copies. Please share your ideas.
Thanks.
Adam Robinson's answer is on the right track, but is not entirely correct. I'm going to try and provide the "long" version (in contrast to his "short" version), and explain along the way where/why I think the solution that he proposes falls short of achieving your ultimate goal.
As the documentation he links to explains, there are three different ways of monitoring changes to the Windows clipboard, each with their own caveats:
Creating a clipboard viewer window that hooks into the clipboard viewer chain and receives notification messages when the contents of the clipboard have been changed by the user. (Available on all versions of Windows, but generally more difficult to code and thus discouraged for newer applications that don't have a specific need for its features.)
Querying the clipboard sequence number, which is a 32-bit value that changes each time the clipboard's contents are changed. Your program calls the Windows API function GetClipboardSequenceNumber once and caches its value, then each time you want to check if the clipboard's contents have changed, you call that same function again and compare its return value to the value you've cached. There are two important caveats here:
This function is only available in Windows 2000 and newer. This is not likely to be a problem if you're writing .NET apps, as versions of the Framework as early as 3.0 dropped W2K support.
This is not a notification method, and you should not call this function repeatedly in a polling loop. That means that you have to manually call the appropriate function and compare the clipboard sequence number. You cannot use this method if you want to "listen in" and be immediately notified whenever the clipboard's contents change, as you describe in your question. The documentation is very explicit here:
This method is more suitable to programs which cache results based on the current clipboard contents and need to know whether the calculations are still valid before using the results from that cache. Note that this is a not a notification method and should not be used in a polling loop. To be notified when clipboard contents change, use a clipboard format listener or a clipboard viewer.
Creating a clipboard format listener, which registers to be notified whenever the clipboard's contents change. This is the ideal solution in your case, because it avoids the complexities of creating a clipboard viewer window (option 1), but also allows you listen in and be notified each time the clipboard's contents are changed (in contrast to option 2).
The problem is that this is only available under Windows Vista and later. If you still have any need to target Windows XP (as most of us do), this is really not an option for you.
Therefore, from the example you provide in the question, it sounds to me like the only option available to you is option 1, creating a clipboard viewer window. The documentation goes into the gory details of how you'd set this up using the SetClipboardViewer function and listening for the WM_DRAWCLIPBOARD and WM_CHANGECBCHAIN messages. Getting this to work right can be a difficult task to do on your own, but fortunately for us .NET developers, others have already done the hard work for us. ("Others", I say, despite having been one of those others myself.)
This article on CodeProject is a good example. It implements three different types of hooks: a mouse hook, a keyboard hook, and a clipboard hook. The only thing you're interested in is the clipboard hook, but you can just add a reference to the DLL in your project to start using its functionality immediately.
If you are interested in the internals of how this works and want to try coding it up yourself, this article appears to be a fantastic description of the specific steps involved.
Use the My.Computer.Clipboard.GetText() function
Also see the msdn page
Check out this MSDN link regarding the clipboard. In particular, this link's anchor should take you to the section of the document about monitoring the clipboard contents.
The short version is that you can monitor either by polling for the sequence number and checking to see if it has changed, or you can register to listen for changes for specific clipboard contents formats. Note that the latter is only available on Vista and above, so you depending on your target platform you may have to stick with polling.
In order to use these functions, you'll have to declare a P/Invoke to the unmanaged function. Here's the PInvoke.net page on the GetClipboardSequenceNumber function, though the declaration here is C#, not VB.NET. The VB.NET syntax should be (I don't have VS in front of me to check):
<DllImport("user32.dll")>
Public Shared Function GetClipboardSequenceNumber() as UInt32
End Function