How do I use GetThemeFont to read font data? - c#

I am trying to use GetThemeFont to read the font data from a visual style, but I can't seem to get it to return anything. Here is how I'm using it:
IntPtr h = OpenThemeData(this.Handle, "Button");
LOGFONT font = new LOGFONT();
int r = GetThemeFont(h, IntPtr.Zero, 1, 1, 210, out font);
CloseThemeData(h);
The return value is always "-2147023728" and font is always null. The place where I put 210 (for TMT_FONT), I'm not really sure what to use there. Any help on this would be much appreciated.

-2147023728 is the decimal equivalent of 0x80070490L, which is the value assigned to E_PROP_ID_UNSUPPORTED. From the "Remarks" section of the documentation of of GetThemeFont:
If the property is not supported for
the specified part and state,
E_PROP_ID_UNSUPPORTED may be returned.
The property is not supported for the part and state combination that you are passing in.

See this gist https://gist.github.com/1219126
You'll never get back anything more than null, or the not supported result. Additionally, using TMT_FONT (210) will drop a nice memory error and clear the stack (for who knows what reason) if you attempt to use it within a managed app.
The internals of either VisualStyleRenderer.GetFont and/or GetThemeFont are inherently flawed. I'm trying to work with some people at MS to address this and provide either a workaround, more documentation or some acknowledgement that this is broken.

Related

monitor html change using hash func

I want to write an application that gets a list of urls.
For each of them I need to monitor periodically if the content has changed.
I thought :
to use HtmlAgilityPack to fetch html content (any other recommendation?)
I don't need to spot the change itself,
so I though to hash the content, save it in the DB
and re-compare the has in the future.
How would you suggest hashing? .net's GetHashCode() ?
I saw this documentation http://support.microsoft.com/kb/307020
which advise using
tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
why?
You should absolutely not use GetHashCode() for this. The documentation explicitly states:
Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework.
The results of GetHashCode can change between runs - all that's guaranteed is that calling it on two equal objects in the same process (possibly AppDomain) will give the same hash code. Indeed, String.GetHashCode's algorithm has changed over time, and in .NET 4 the 32-bit implementation is different to the 64-bit implementation.
If you want to use hashing, use MD5, SHA1 etc - something with a specified algorithm which will not change. (Note that these operation on binary data rather than string data, which is probably more appropriate too - you don't need to bother decoding the data as text.)
It's not clear to me whether refetching periodically is really the best idea though - do these servers not support last modified times, etags etc?
As you have asked for suggestions. I would have used this method instead
WebClient client = new WebClient();
String htmlCode = client.DownloadString("http://google.com");
And i would have saved this string in my DB. After the particular interval i could have compared them again.
But yes I do agree the string size would be really be large.
If I just want to get a alert on the fact the content has changed some how. I would use MD5. As the result size of an MD5 string is only 27 characters.
Hence easier to compare and store in DB

Is there any plugin for VS or program to show type and value etc... of a C# code selection?

What I want to do is be told the type, value (if there is one at compile-time) and other information (I do not know what I need now) of a selection of an expression.
For example, if I have an expression like
int i = unchecked((short)0xFF);
selecting 0xFF will give me (Int32, 255), while selecting ((short)0xFF) will give me (Int16, 255), and selecting i will give me (Int32, 255).
Reason why I want such a feature is to be able to verify my assumptions. It's pretty easy to assume that 0xFF is a byte but it is actually an int. I could of course refer to the C# Language Specifications all the time, but I think it's inefficient to have to refer to it everytime I want to check something out. I could also use something like ANTLR but the learning curve is high.
I do intend to read the entire specs and learn ANTLR and about compilers, but that's for later. Right now I wish to have tools to help me get the job done quickly and accurately.
Another case in point:
int? i = 0x10;
int? j = null;
int x;
x = (i >> 4) ?? -1;//x=1
x = (j >> 4) ?? -1;//x=-1
It may seem easy to you or even natural for the bottom two lines in the code above. (Maybe one should avoid code like these, but that's another story) However, what msdn says about the null-coalescing operator is lacking information to tell me that the above code ((i>>4)??) is legal (yet it is, and it is). I had to dig into grammar in the specs to know what's happening:
null-coalescing-expression
conditional-or-expression
conditional-and-expression
exclusive-or-expression
and-expression
equality-expression
relational-expression
shift-expression
shift-expression right-shift additive-expression
... (and more)
Only after reading so much can I get a satisfactory confirmation that it is valid code and does what I think it does. There should be a much simpler way for the average programmer to verify (not about validity, but whether it behaves as thought or not, and also to satisfy my curiosity) such code without having to dive into that canonical manual. It doesn't necessary have to be a VS plugin. Any alternative that is intuitive to use will do just as well.
Well, I'm not aware of any add-ins that do what you describe - however, there is a trick you can use figure out the type of an expression (but not the compile-time value):
Assign the expression to a var variable, and hover your mouse over the keyword var.
So for example, when you write:
var i = unchecked((short)0xFF);
and then hover your mouse over the keyword var, you get a tooltip that says something like:
Struct System.Int16
Represents a 16-bit signed integer.
This is definitely a bit awkward - since you have to potentially change code to make it work. But in a pinch, it let's you get the compiler to figure out the type of an expression for you.
Keep in mind, this approach doesn't really help you once you start throwing casts into the picture. For instance:
object a = 0xFF;
var z = (string)a; // compiles but fails at runtime!
In the example above, the IDE will dutifully report that the type of var z is System.String - but this is, of course, entirely wrong.
Your question is a little vague on what you are looking for, so I don't know if "improved" intellisense solves it, but I would try the Productivity Power Tools.

Does PrinterSettings.GetHdevmode() have a bug?

I would like to be able to change the printer properties without bringing up the printer properties window...
Using the DocumentProperties (imported from winspool.drv) function has so far failed, because while it is easy to suppress the dialog from showing up, it seems that the value returned by PrinterSettings.GetHdevmode() is not reflecting the PrinterSettings that is calling it, but instead the value from the previous printer properties returning OK. For example, this gives me the previous (wrong) values from the last call to the properties, instead of the values it should have from the PrinterSettings object:
IntPtr hdevmode = PrinterSettings.GetHdevmode(PrinterSettings.DefaultPageSettings);
PrinterSettings.SetHdevmode(hdevmode);
PrinterSettings.DefaultPageSettings.SetHdevmode(hdevmode);
So does GetHdevmode have a bug or is this what its supposed to do? Is there a C# work around for this or does anyone even have any information about it? I have been hard pressed even to find info on the topic.
Thanks in advance for any insight.
EDIT:
I didn't want to make this too personal of a problem, but hopefully having all the info in this case can provide an answer that is a useful solution for others too.
Here is a C++ DLL I have written in order to have a workaround for this issue. Its not currently working - it changes other memory such as copies, and doesn't succeed in changing the "underlying" papersize. I thought all I needed to do was specify the out buffer flag in order to make the changes?
extern "C" __declspec(dllexport) DEVMODE* __stdcall GetRealHDevMode(int width, int height, char *printerName, DEVMODE* inDevMode)
{
//declare handles and variables
HANDLE printerHandle;
LPHANDLE printerHandlePointer(&printerHandle);
//get printer handle pointer
OpenPrinter((LPWSTR)printerName, printerHandlePointer, NULL);
//Get size needed for public and private devmode data and declare devmode structure
size_t devmodeSize = DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, NULL, NULL, 0);
DEVMODE* devmode = reinterpret_cast<DEVMODE*>(new char[devmodeSize + sizeof(DEVMODE) + sizeof(inDevMode->dmDriverExtra)]);
//lock memory
GlobalLock(devmode);
//fill the out buffer
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, NULL, DM_OUT_BUFFER);
//change the values as required
devmode->dmPaperWidth = width;
devmode->dmPaperLength = height;
devmode->dmPaperSize = DMPAPER_USER;
devmode->dmFields &= ~DM_PAPERSIZE;
devmode->dmFields &= ~DM_PAPERLENGTH;
devmode->dmFields &= ~DM_PAPERWIDTH;
devmode->dmFields |= (DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH);
//input flag on now to put the changes back in
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);
//unlock memory
GlobalUnlock(devmode);
//return the devmode that was used to alter the settings
return devmode;
}
I figured the C++ code was enough to change the settings, so all I do in C# is this:
public PrinterSettings ChangePrinterProperties(PrinterSettings inPrinterSettings)
{
IntPtr TemphDevMode = inPrinterSettings.GetHdevmode(inPrinterSettings.DefaultPageSettings);
IntPtr hDevMode = GetRealHDevMode((int)(inPrinterSettings.DefaultPageSettings.PaperSize.Width * 2.54F),
(int)(inPrinterSettings.DefaultPageSettings.PaperSize.Height * 2.54F),
inPrinterSettings.PrinterName, TemphDevMode);
GlobalFree(hDevMode);
return inPrinterSettings;
}
UPDATE: Changed up the order a bit with dmPaperSize and dmFields. Improved results; not quite there yet.
UPDATE 2: Okay, I found a microsoft page that says the documentation is wrong. MSDN says to set dmPaperSize to 0 when you want to specify width and height whereas the Microsoft Support correction says to set it to DMPAPER_USER. http://support.microsoft.com/kb/108924
There are 2 problems with the way you are specifying the paper size in the DEVMODE:
(1) If you specify DM_PAPERWIDTH or DM_PAPERLENGTH or both, you MUST NOT also set the DM_PAPERSIZE bit. It depends on the printer driver, but many drivers will ignore DM_PAPERLENGTH/WIDTH in the above code.
(2) Many drivers don't support DM_PAPERLENGTH/WIDTH at all. With such drivers, you simply cannot set the paper size like you are trying to do above. You can only select one of the predefined dmPaperSizes.
You can use DeviceCapabilities(DC_FIELDS) to determine if your driver supports DM_PAPERLENGTH/WIDTH.
You can use DeviceCapabilities(DC_PAPERS) to enumerate the allowable dmPaperSizes.

Question on how these 2 lines of code work

I am reading this article on how to work with AD via C#. Half way through the article, the below code is presented.
The user account properties are checkboxes. Does anyone have any idea what the below line of code will return for a checked checkbox? What if more than 1 checkbox is checked? I'd have thought a bool being returned would be more intuitive?
//Add this to the create account method
int val = (int)newUser.Properties["userAccountControl"].Value;
//newUser is DirectoryEntry object
Why do we do the logical or below? How does it work between an int and the second value (is that a byte?)
newUser.Properties["userAccountControl"].Value = val | 0x80000;
//ADS_UF_TRUSTED_FOR_DELEGATION
I know that sounds very naive...
Thanks
The userAccountControl property contains a two byte value in which each single bit has a significant meaning. If the bit is on, then some option is used - if it's not on, then the option is not present.
This is more compact and more space optimized than having a gazillion of booleans. Also, many "older" Win16 and Win32 API just simply work this way.
The bitwise "AND" operator is used to check for the presence of such a single bit:
if (newUser.Properties["userAccountControl"].Value & 0x400 == 0x400)
in this case, the 0x400 bit is set.
In order to actually set a bit, you use the bitwise "OR" operator:
newUser.Properties["userAccountControl"].Value = val | 0x800
This sets the "0x800" bit.
It's basic bit-wise boolean logic, really. A bit messy, indeed - but .NET has some help to make things a bit easier (check out the BitArray data type, for instance)
userAccountControl is a flag field, that's why they put it into an int.
See http://support.microsoft.com/kb/305144 for more information.
Based on the information that you are giving, I would guess that they are using a flags type system to indicate selected items. Each option has a specific value, and they are added up so you can get back which are selected.
This would be proved by the logical or that is used to see if a specific value is included.

String Comparison set to boolean variable

I assume this should be fine
bool prefMatch = false;
// Is the frequency the same?
prefMatch = string.Compare(user.Frequency, pref.Action.ToString()) == 0;
so if user.Frequency is "3" and pref.Action.ToString() is "3" then it should set the prefMatch to true right? I'm getting false and I've definitely checked the 2 values in the watch tab in VS 2008 just to be sure they're the same
You can just use ==
prefMath = (user.Frequency == pref.Action.ToString());
Though string.Compare will also work. I suggest there is a problem elsewhere.
-- Edit
Also, just for completeness, there is no point assigning a variable to something, and then assigning it again directly after. It's slightly confusing to do so, so better to leave it unassigned, or assign it all in one spot. This way the compiler can help you if you have a case where it doesn't get assigned like you think. It is, obviously, acceptable to assign first if you wrap the second assignment in a try/catch though.
In situations like these, it's sometimes tempting to point the finger of blame at third-party code, as you've done here. Sometimes, this is justified - but not here. String.Compare is a central, extremely-well-tested piece of the .NET Framework. It's not failing. I guarantee it.
What I find helpful in these situations is to isolate the failure. Write a small, self-contained test case that attempts to demonstrate the problem. Write it with as few dependencies as possible. Make it a stand-alone console application, if possible. Post it here. If we can take it, compile and run it, and reproduce the problem, we can help you. I'd bet money, though, that in the course of creating this test case, you'll experience a head-slapping moment - "of course!" - and realize what the problem is.
Maybe the string(s) contain unprintable characters ?
To check, I'd do something like :
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(user.Frequency);
byte[] b2 = System.Text.Encoding.UTF8.GetBytes(pref.Action.ToString());
then compare the contents of b1 and b2.

Categories

Resources