There are several places that talk about how to get an icon from a file extension such as this one and this other one. After several hours of playing around with this kind of projects I have managed to build something like:
private void addButton_Click(object sender, System.EventArgs e)
{
System.Drawing.Icon temp = IconReader.GetFileIcon(".cs", IconReader.IconSize.Large, false);
pictureBox1.Image = temp.ToBitmap();
}
the execution of that button gets me:
but I am trying to actually get the large icon. Note how the icons on windows are much bigger:
How could I get that icon instead of the smaller one. I have spend so much time changing the other programs. Moreover I will like to make it work with wpf and most of the examples are with windows forms. I would appreciate if I can get an example of how to extract a files icon instead of modifying and entire project. If that is not possible that would still be very helpful and I will appreciate. It's just that I am not that good of a programmer and it took me a lot of time to modify the other examples.
here's a solution http://www.codeproject.com/KB/WPF/filetoiconconverter.aspx
The code you're referencing only uses 2 sizes:
public const uint SHGFI_LARGEICON = 0x000000000; // get large icon
public const uint SHGFI_SMALLICON = 0x000000001; // get small icon
to get the extra_large size, you need to add your own define (and add another enum for calling functions):
public const uint SHGFI_EXTRALARGEICON = 0x000000002; // get extra large icon
or if you just want a quick fix, replace 0x000000000 with 0x000000002 in the original large definition.
Here are all icon sizes:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185%28v=vs.85%29.aspx
You cannot make ShGetFileInfo return ExtraLarge and Jumbo icons.
Instead,
1) Call ShGetFileInfo with the SysIconIndex ( 0x000004000) flag
2) Get the System Imagelist with the proper size using ShGetImageList
3) Get the HICON using ImageList_GetIcon and the .iIcon value from SHFILEINFO.
Related
Im making a Random Generator with Windows Forms with Images and I use the random pick with resources pictureBox1.Image = Properties.Resources.heart;
Now, the "heart" should get removed from the List, to prevent getting "heart" again.
Here I thought, that I just use int firstCard = randomCard.Next(cards.Count); and I want to use the int firstCard as Properties.Resources.cards[firstCard], because behind Properties.Resources. comes the resource name. But the string doesnt work there, and I dont know how to fix that. Pls help.
Thank you
Pults
Add all your images to a List<Image> - if you have 100 images your list will end up with 100 things
Pick one at random and also remove it. Make the upper bound of random the number of things in the list
//do this once outside the loop that adds images: var r = new Random();
Then the loop that adds images
var x = r.Next(imageList.Count);
var i = inageList[x]; //get the image
imageList.RemoveAt(x); //can't get it again
Note that setting the image of a picture box cannot be done in addition; you'll need multiple picture boxes
Side note, you might find it easier to keep your images in an ImageList (easier to index numerically) - the documentation for it also has some useful/helpful example codes that iteratively draws images into a PictureBox
Also, someone else (maybe doing the same exercise as you :) ) wondered how to get images by string name..
Oh yeah, someone asked the same, didnt find it.
Yea the "ResourceManager.GetObject" is exactly what I needed.
Thanks for the quick response and instant solve!
I need to detect the code page the keyboard input is using while user is entering data into application fields.
I tried to use System.Text.Encoding.Default.CodePage; but it gives the code page of what is configured in regional settings.
Then i thought Console.InputEncoding.CodePage; could work, but still, code page is the same as with the above example.
The problem is, user may have a Cyrilic (Windows-1251) code page because of the regional settings, but he may wish to use a different input language. The data user enters is then saved to a file, and that file can be opened in a system which has a different regional settings. Along with text, i am saving code page number, so my app can load the file and display the text correctly. I cannot use Unicode for cross compatibility with a different app which does not support unicode.
Disclaimer: I'm not an expert on the globalization side of the .NET Framework, so it might wrap equivalent functionality somewhere or another. If so, and you can locate it, great—use that instead. I thought maybe Globalization.CultureInfo.CurrentCulture would return the information we're looking for, but alas it does not; instead, it appears to return the system default culture even if the keyboard layout is changed. I stopped investigating. The described approach is guaranteed to work, albeit with a little extra code.
To determine the code page associated with a particular keyboard layout, you can call the Win32 GetLocaleInfo function, specifying the language ID associated with the current keyboard layout. You request this using the LOCALE_IDEFAULTANSICODEPAGE constant.
To call these functions from a .NET application, you will need to use P/Invoke. You'll also need to define function equivalents for some essential macros.
const int LOCALE_IDEFAULTANSICODEPAGE = 0x1004;
const int LOCALE_RETURN_NUMBER = 0x20000000;
const int SORT_DEFAULT = 0x0;
static int LOWORD(IntPtr val)
{
return (unchecked((int)(long)val)) & 0xFFFF;
}
static int MAKELCID(int languageID, int sortID)
{
return ((0xFFFF & languageID) | (((0x000F) & sortID) << 16));
}
static int MAKELANGID(int primaryLang, int subLang)
{
return ((((ushort)(subLang)) << 10) | (ushort)(primaryLang));
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetLocaleInfo(int locale,
int lcType,
out uint lpLCData,
int cchData);
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint idThread);
Use it like this:
// Get the keyboard layout for the current thread.
IntPtr keybdLayout = GetKeyboardLayout(0);
// Extract the language ID from it, contained in its low-order word.
int langID = LOWORD(keybdLayout);
// Call the GetLocaleInfo function to retrieve the default ANSI code page
// associated with that language ID.
uint codePage = 0;
GetLocaleInfo(MAKELCID(langID, SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
out codePage,
Marshal.SizeOf(codePage));
When tested with a US English keyboard layout, codePage is 1252. After switching to a Greek keyboard layout, codePage is 1253. Likewise, Turkish returns 1254, and the various cyrillic languages return 1251. Exactly as documented.
It is worth noting that, in the linked documentation, these API functions are indicated as having been superseded. With modern versions of Windows, Microsoft has moved to named locales, first because they were out of room for numeric IDs, and second to enable support for custom locales. But you will need to use the old functions for what you're doing. Modern Windows applications don't use ANSI code pages, either.
However, you do need to be aware of this fact, because it may come back to bite you. There are keyboard layouts that do not have an associated ANSI code page. For these, only Unicode can be used. The above code will return CP_ACP (which is equivalent to the numeric value 0). Handling that is up to you. You will either need to display an error, or save the file as Unicode (albeit breaking the other application, but complying with user expectations).
Finally, I must point out that if you cache the codePage value, it may become stale since the user can change the keyboard layout at any time. It is probably easiest just not to cache the value, determining it each time you perform a save. But if you want to cache it, you will need to handle the WM_INPUTLANGCHANGE message and update your cached value in response.
I ask here about XNA and not on it's official forums because people from my country are not allowed to sign in to the new XNA website.
Well, these are my questions:
I want to use some 2D images I create in Paint Shop Pro/Photo Shop/Paint, but for some reason I need to use web safe pallet and such settings for it to be displayed currently (I use transparency).
could any1 please explain to me how can I use transparency & other settings (while creating & saving the image) so that the XNA (4.0) could display it correctly?
By the way, it might be that I just need some 1 to explain to me how to set the "GraphicsDevice"-s settings to work with transparency layer/channel.
I really do try to do things as I am supposed to (by Microsoft's view) & thus I use the content pipeline for ALL of my content loading (including classes initiation data files).
I use .txt files for storing my class initiation data & I edit them with simple good old notepad (++ :P).
Now, the problem is that all I managed to do is loading the .txt file as a really long string instead of creating a new instance of my GameDataFile class.
because of that I was forced to do it in 2 steps:
Step 1:
string tempStrData = content.load<string>("data/filename").Replace("\r", "");
/* Loads a string from a file (the string is the whole file!) */
Step 2:
GameDataFile gameDataFile = new GameDataFile(tempStrData.Split('\n'));
/* Sends the string to my GameDataFile class constructor which knows how to handle that string and break it to it's data elements (ints, strings vectors, etc...) */
I want to upgrade it to be of the following form:
GameDataFile gameDataFile = content.load<GameDataFile>("data/fileName");
I think I should do this using a custom Content pipeline Processor, any opinions if I'm right & how should I achieve that?
P.S please don't make me to use public members as I always set that to private and I hate and strictly forbid myself from using the C#-ONLY-get-&-set methods.
Thanks In Advance, Tal A.
For your first question, set the blendstate to AlphaBlend when you begin your SpriteBatch:
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null);
I save my images as PNGs in PhotoShop which allows transparency.
Edit: Unless you're referring to 3D textures. If so I'll have to revise my answer
Edit: As for question 2, this example on App Hub shows how to do it.
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.
I want to be able to compare an image taken from a webcam to an image stored on my computer.
The library doesn't need to be one hundred percent accurate as it won't be used in anything mission critical (e.g. police investigation), I just want something OK I can work with.
I have tried a demonstration project for Image Recognition from CodeProject, and it only works with small images / doesn't work at all when I compare an exact same image 120x90 pixels (this is not classified as OK :P ).
Has there been any success with image recognition before?
If so, would you be able to provide a link to a library I could use in either C# or VB.NET?
You could try this: http://code.google.com/p/aforge/
It includes a comparison analysis that will give you a score. There are many other great imaging features of all types included as well.
// The class also can be used to get similarity level between two image of the same size, which can be useful to get information about how different/similar are images:
// Create template matching algorithm's instance
// Use zero similarity to make sure algorithm will provide anything
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
// Compare two images
TemplateMatch[] matchings = tm.ProcessImage( image1, image2 );
// Check similarity level
if (matchings[0].Similarity > 0.95)
{
// Do something with quite similar images
}
You can exactly use EmguCV for .NET.
I did it simply. Just download the EyeOpen library here.
Then use it in your C# class and write this:
use eyeopen.imaging.processing
Write
ComparableImage cc;
ComparableImage pc;
int sim;
void compare(object sender, EventArgs e){
pc = new ComparableImage(new FileInfo(files));
cc = new ComparableImage(new FileInfo(file));
pc.CalculateSimilarity(cc);
sim = pc.CalculateSimilarity(cc);
int sim2 = sim*100
Messagebox.show(sim2 + "% similar");
}