.Net - Detecting the Appearance Setting (Classic or XP?) - vb.net

I have some UI in VB 2005 that looks great in XP Style, but goes hideous in Classic Style.
Any ideas about how to detect which mode the user is in and re-format the forms on the fly?
Post Answer Edit:
Thanks Daniel, looks like this will work. I'm using the first solution you posted with the GetCurrentThemeName() function.
I'm doing the following:
Function Declaration:
Private Declare Unicode Function GetCurrentThemeName Lib "uxtheme" (ByVal stringThemeName As System.Text.StringBuilder, ByVal lengthThemeName As Integer, ByVal stringColorName As System.Text.StringBuilder, ByVal lengthColorName As Integer, ByVal stringSizeName As System.Text.StringBuilder, ByVal lengthSizeName As Integer) As Int32
Code Body:
Dim stringThemeName As New System.Text.StringBuilder(260)
Dim stringColorName As New System.Text.StringBuilder(260)
Dim stringSizeName As New System.Text.StringBuilder(260)
GetCurrentThemeName(stringThemeName, 260, stringColorName, 260, stringSizeName, 260)
MsgBox(stringThemeName.ToString)
The MessageBox comes up Empty when i'm in Windows Classic Style/theme, and Comes up with "C:\WINDOWS\resources\Themes\luna\luna.msstyles" if it's in Windows XP style/theme. I'll have to do a little more checking to see what happens if the user sets another theme than these two, but shouldn't be a big issue.

Try using a combination of GetCurrentThemeName (MSDN Page) and DwmIsCompositionEnabled
I linked the first to PInvoke so you can just drop it in your code, and for the second one you can use the code provided in the MSDN comment:
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled();
See what results you get out of those two functions; they should be enough to determine when you want to use a different theme!

Personally, I use the following to see if the app is running under themed:
if (Application.RenderWithVisualStyles)
{
// you're themed
}

There's the IsThemeActive WinAPI function.

Related

Dll methods are not invoked on windows server 2008

I'm trying to invoke on dll method from an ASP.net web. It's working on a W2003 server but the same dll and the same web is crashing on w2008 server R2 with IIS 7.5.I'm doing like this to import the dll:
<DllImport("Cripto.dll")> _
Public Shared Function DesCipher(ByVal uiMode As Integer, ByVal uiLength As Integer, ByVal szSourceData As String) As String
End Function
I have tried a 64 bits dll compile but the problem remains.
I'm going mad...
Please Help!
Finally I have found the clue.
It is a memory location problem. The main function was returning an array like this:
char retorno[10000];
The function was declared in the dll code as "char*"
By changing these lines:
ULONG ulSize = strlen((char*)retorno) + sizeof(char);
char* pszReturn = NULL;
pszReturn = (char*)::GlobalAlloc(GMEM_FIXED, ulSize);
strcpy(pszReturn, (char*)retorno);
return pszReturn;
instead of
return ((char *)retorno)
Now it's working.

Create a Bitmap (.NET) from HBITMAP

I'm using C++/CLI and I have a raw HBITMAP called hStrip, I have to display this in a PictureBox, so I found the following function System::Drawing::Image::FromHbitmap, however this takes IntPtr and I wondered if I need to convert my raw HBITMAP to IntPtr before passing it in or if I could get away passing it in like this?
If I need to convert, how should I convert? I haven't really found the conversion this way. I did find it the other way though.
A simple cast gets the job done:
HBITMAP hBmp = NULL;
// Assign hBmp
//...
Bitmap^ bmp = Bitmap::FromHbitmap((IntPtr)hBmp);
DeleteObject(hBmp); // okay to destroy now

How load the Dll according to platform

I have a dll for 32bit and 64bit and now I want that my exe call the dll from according to solution platform,means when x64 is set then the dll of 64bit will call.For this I declare a function GetPlatform().
Public Function GetPlateform() As String
Dim var1 As String
If (IntPtr.Size = 8) Then
var1 = hellox64
Else
var1 = hello
End If
Return var1
End Function
and when the form load
this var1 is assign to var and finally.
Public Declare Function function1 Lib "var" (ByVal Id As Integer) As Integer
But When I debug the code "DllNotFoundException" is ocuured.
NOTE:The dll is in vc++.
Store your native dlls into subfolders and hint the Library Loader by filling accordingly the PATH process environment variable with the path to the correct version to load.
For instance, given this tree layout...
Your_assembly.dll
|_NativeBinaries
|_x86
|_your_native.dll
|_amd64
|_your_native.dll
...and this code (sorry, C#, no VB.Net :-/ )...
internal static class NativeMethods
{
private const string nativeName = "your_native";
static NativeMethods()
{
string originalAssemblypath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
string currentArchSubPath = "NativeBinaries/x86";
// Is this a 64 bits process?
if (IntPtr.Size == 8)
{
currentArchSubPath = "NativeBinaries/amd64";
}
string path = Path.Combine(Path.GetDirectoryName(originalAssemblypath), currentArchSubPath);
const string pathEnvVariable = "PATH";
Environment.SetEnvironmentVariable(pathEnvVariable,
String.Format("{0}{1}{2}", path, Path.PathSeparator, Environment.GetEnvironmentVariable(pathEnvVariable)));
}
[DllImport(nativeName)]
public static extern int function1(int param);
[DllImport(nativeName)]
public static extern int function2(int param);
}
...function1 and function2 would be dynamically bound to either the 32 or 64 bits version of the native code, depending on the size of an IntPtr (more on this in this post from Scott Hanselman or this StackOverflow question).
Note 1: This solution is especially useful when both versions of the dll bear the same name or if you're not willing to duplicate every extern references.
Note 2: This has already been successfully implemented in LibGit2Sharp.
No, you cannot dynamically create a reference to the DLL in a lib statement. However, you may (disclaimer: have not tried) be able to create two references and call the appropriate one in your code.
Public Declare Function Function132 Lib "My32BitLib.DLL" Alias "function1" (ByVal Id As Integer) As Integer
Public Declare Function Function164 Lib "My64BitLib.DLL" Alias "function1" (ByVal Id As Integer) As Integer
You will then need to branch on the platform and call the appropriate alias function name (Function132 or Function164) depending on the platform.

File I/O in a C++ DLL?

I am trying to build a dll that reads a text file to populate a 2d array, then change that array as needed. I'm using a VB GUI to access it. The overall program is a micromouse simulator in which the user is able to customize the wall placement in a 5x5 maze, as well as mouse start position and goal placement, and allow the search algorithm (dll) to solve it. Here's the code inside my dll:
/*testDLL.cpp*/
#include "testDLL.h"
#include <stdio.h>
FILE *maze;
char mazearray[12][12];
void _stdcall wallfunction(int x, int y){
maze = fopen ("C:\Users\Public\Documents\5x5mazedefault.txt", "r");
fread (mazearray, sizeof(mazearray), 1, maze);
fclose(maze);
if (mazearray[x][y] == 'X'){
mazearray[x][y] = ' ';
}
else if (mazearray[x][y] == ' '){
mazearray[x][y] = 'X';
}
}
I want to be able to put in two input variables as the index of the matrix and add or subtract a wall from that location. Whenever I try to call the function from VB, it sends me a message: PInvoke restriction cannot return variants. The function returns nothing, so I don't understand...
Here's the declaration statement inside my VB program:
Private Declare Function wallfunction Lib "C:\Path\Path\testDLL.dll" (ByVal x As Integer, ByVal y As Integer)
I'm aware I'm not going to be able to call the fread function everytime the user wants to change a wall; I'm just trying to get this working once first. Any thoughts?
Change Function to Sub in your Declare statement in VB. This is because your C++ function returns void.

How to get HWND of a windowless ATL control?

I created a ATL windows less control and the class definition is like this:
class ATL_NO_VTABLE CRSPClient :
public IObjectSafetyImpl<CRSPClient, INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA>,
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IRSPClient, &IID_IRSPClient, &LIBID_axBanckleRSPClientLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IPersistStreamInitImpl<CRSPClient>,
public IOleControlImpl<CRSPClient>,
public IOleObjectImpl<CRSPClient>,
public IOleInPlaceActiveObjectImpl<CRSPClient>,
public IQuickActivateImpl<CRSPClient>,
public IViewObjectExImpl<CRSPClient>,
public IOleInPlaceObjectWindowlessImpl<CRSPClient>,
#ifdef _WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctly
public IObjectSafetyImpl<CRSPClient, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
#endif
public CComCoClass<CRSPClient, &CLSID_RSPClient>,
public CComControl<CRSPClient>
Then for some purpose I need to post message to the window. I tried to get the handle of the window in quite many ways and ALL of them failed:
HWND CRSPClient::GetHwnd()
{
HWND hwndRet = NULL;
// hwndRet = m_hWnd;
//IOleInPlaceActiveObjectImpl<CRSPClient>::GetWindow(&hwndRet);
//IOleWindow<CRSPClient>::GetWindow(&hwndRet);
//this->m_spInPlaceSite->GetWindow(&hwndRet);
//CComQIPtr<IOleInPlaceSite> spSite = this->m_spClientSite;
//spSite->GetWindow(&hwndRet);
//hwndRet = ::WindowFromDC(GetDC());
return hwndRet;
}
Anybody know be there any way to get the HWND?
OMG I'm totally frustrated by microsoft's great ATL framework!
The whole point of the windowless control is that it works without a window handle. If you wanted to use window handle in case it, by any chance, exists and the control falled back into windowed mode, then it's easy: m_hWndCD.
If otherwise you have to have a window, then you have m_bWindowOnly to flag in constructor and indicate that you will need a HWND:
Flag indicating the control should be windowed, even if the container supports windowless controls.
If you still want it windowless and need a window just sometimes, under certain condition that come up on runtime, you always have an option to create a private message only window and dispatch messages through it.
Here is some code taken from Microsoft's Direct3D ATL sample. I haven't tested it yet.
// Get the window we need to use. This will either be the window that has already
// been created if we are window. If we are windowless the HWND of the client
// will be retrieved from the HDC.
void GetOurWindow()
{
// If we're windowless we still need an HWND for Direct3d
if (m_bWndLess)
{
HDC hDC;
// Get the HDC from the client
m_spInPlaceSite->GetDC(NULL, OLEDC_NODRAW, &hDC);
m_hOurWnd = WindowFromDC(hDC);
#if 1
// Code to make VB5 paint properly now it has clipped it's own hDC
RECT rect;
::GetClientRect(m_hOurWnd,&rect);
HRGN hRegion = CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
SelectClipRgn(hDC,hRegion);
#endif
m_spInPlaceSite->ReleaseDC(hDC);
}
else
m_hOurWnd = m_hWnd;
}