Bitwise Operations
Here’s a great resource for doing some common bit-wise tasks.
Bit Twiddling Hacks (http://graphics.stanford.edu/~seander/bithacks.html)
Bitwise OperationsJanuary 19th, 2009
Here’s a great resource for doing some common bit-wise tasks. Bit Twiddling Hacks (http://graphics.stanford.edu/~seander/bithacks.html) C# WPF Singleton ApplicationJanuary 8th, 2009
There are several tutorials out there for C# that show you how to make an application so that it can only have one instance. However most of the example code out there doesn’t do it properly or it uses the FindWindow function which is not the proper way to identify an application. The code below basically registers a window message using your application’s GUID. Then it sends that message to all the open processes, seeing if any will respond to it. Processes that do respond to the window message that we registered, are ours, because we have code that also responds to our own window message. Once we identify that a window is ours, we then send a COPYDATA window message to it with the command line parameter that we want to pass to the instance of our application that is visible to the user. Source Code:
public partial class App : Application
{
private static Mutex SingleMutex;
public static uint MessageId;
private void Application_Startup(object sender, StartupEventArgs e)
{
IntPtr Result;
IntPtr SendOk;
Win32.COPYDATASTRUCT CopyData;
string[] Args;
IntPtr CopyDataMem;
bool AllowMultipleInstances = false;
Args = Environment.GetCommandLineArgs();
// TODO: Replace {00000000-0000-0000-0000-000000000000} with your application's GUID
MessageId = Win32.RegisterWindowMessage("{00000000-0000-0000-0000-000000000000}");
SingleMutex = new Mutex(false, "AppName");
if ((AllowMultipleInstances) || (!AllowMultipleInstances && SingleMutex.WaitOne(1, true)))
{
new Main();
}
else if (Args.Length > 1)
{
foreach (Process Proc in Process.GetProcesses())
{
SendOk = Win32.SendMessageTimeout(Proc.MainWindowHandle, MessageId, IntPtr.Zero, IntPtr.Zero,
Win32.SendMessageTimeoutFlags.SMTO_BLOCK | Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
2000, out Result);
if (SendOk == IntPtr.Zero)
continue;
if ((uint)Result != MessageId)
continue;
CopyDataMem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.COPYDATASTRUCT)));
CopyData.dwData = IntPtr.Zero;
CopyData.cbData = Args[1].Length*2;
CopyData.lpData = Marshal.StringToHGlobalUni(Args[1]);
Marshal.StructureToPtr(CopyData, CopyDataMem, false);
Win32.SendMessageTimeout(Proc.MainWindowHandle, Win32.WM_COPYDATA, IntPtr.Zero, CopyDataMem,
Win32.SendMessageTimeoutFlags.SMTO_BLOCK | Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
5000, out Result);
Marshal.FreeHGlobal(CopyData.lpData);
Marshal.FreeHGlobal(CopyDataMem);
}
Shutdown(0);
}
}
}
/***********************************************************************/
public partial class Main : Window
{
private void Window_Loaded(object sender, RoutedEventArgs e)
{
HwndSource Source;
Source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
Source.AddHook(new HwndSourceHook(Window_Proc));
}
private IntPtr Window_Proc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam, ref bool Handled)
{
Win32.COPYDATASTRUCT CopyData;
string Path;
if (Msg == Win32.WM_COPYDATA)
{
CopyData = (Win32.COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(Win32.COPYDATASTRUCT));
Path = Marshal.PtrToStringUni(CopyData.lpData, CopyData.cbData / 2);
if (WindowState == WindowState.Minimized)
{
// Restore window from tray
}
// Do whatever we want with information
Activate();
Focus();
}
if (Msg == App.MessageId)
{
Handled = true;
return new IntPtr(App.MessageId);
}
return IntPtr.Zero;
}
}
/***********************************************************************/
public class Win32
{
public const uint WM_COPYDATA = 0x004A;
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
[Flags]
public enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0000,
SMTO_BLOCK = 0x0001,
SMTO_ABORTIFHUNG = 0x0002,
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
}
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32.dll")]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam,
SendMessageTimeoutFlags fuFlags, uint uTimeout, out IntPtr lpdwResult);
}
C# String Wildcard ComparsionJanuary 8th, 2009
Here are some string extensions that I use to compare wildcards. CompareWildcard compares only one wildcard (ie “*.txt”), while CompareWildcards compares multiple wildcards (ig “*.txt;*.zip;”). Usage Example:
string Path = "c:\readme.txt";
if (Path.CompareWildcards("*.txt;*.zip;", true) == true)
{
// Path matches wildcard
}
Source code:
public static bool CompareWildcards(this string WildString, string Mask, bool IgnoreCase)
{
int i = 0;
if (String.IsNullOrEmpty(Mask))
return false;
if (Mask == "*")
return true;
while (i != Mask.Length)
{
if (CompareWildcard(WildString, Mask.Substring(i), IgnoreCase))
return true;
while (i != Mask.Length && Mask[i] != ';')
i += 1;
if (i != Mask.Length && Mask[i] == ';')
{
i += 1;
while (i != Mask.Length && Mask[i] == ' ')
i += 1;
}
}
return false;
}
public static bool CompareWildcard(this string WildString, string Mask, bool IgnoreCase)
{
int i = 0, k = 0;
while (k != WildString.Length)
{
switch (Mask[i])
{
case '*':
if ((i + 1) == Mask.Length)
return true;
while (k != WildString.Length)
{
if (CompareWildcard(WildString.Substring(k + 1), Mask.Substring(i + 1), IgnoreCase))
return true;
k += 1;
}
return false;
case '?':
break;
default:
if (IgnoreCase == false && WildString[k] != Mask[i])
return false;
if (IgnoreCase && Char.ToLower(WildString[k]) != Char.ToLower(Mask[i]))
return false;
break;
}
i += 1;
k += 1;
}
if (k == WildString.Length)
{
if (i == Mask.Length || Mask[i] == ';' || Mask[i] == '*')
return true;
}
return false;
}
Please feel free to post fixes, and suggestions in the comments below. C# Convert Hex String To/From Byte Array, FAST!June 26th, 2008
I previously wrote about how to quickly convert a byte array to its hex representation and back again in C. Now I’ve converted the same source code to C#. Even though there is a built in method using String.Format, it is too slow. Source Code:
public static string ByteArrayToHexString(byte[] Bytes)
{
StringBuilder Result = new StringBuilder();
string HexAlphabet = "0123456789ABCDEF";
foreach (byte B in Bytes)
{
Result.Append(HexAlphabet[(int)(B >> 4)]);
Result.Append(HexAlphabet[(int)(B & 0xF)]);
}
return Result.ToString();
}
public static byte[] HexStringToByteArray(string Hex)
{
byte[] Bytes = new byte[Hex.Length / 2];
int[] HexValue = new int[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F };
for (int x = 0, i = 0; i < Hex.Length; i += 2, x += 1)
{
Bytes[x] = (byte)(HexValue[Char.ToUpper(Hex[i + 0]) - '0'] << 4 |
HexValue[Char.ToUpper(Hex[i + 1]) - '0']);
}
return Bytes;
}
Windows API: A SET without a GET?!!June 9th, 2008
How is it possible that Microsoft didn’t introduce PBM_GETBKCOLOR/PBM_GETBARCOLOR until Windows Vista? I mean, I can’t imagine it! The progress bar messages PBM_SETBKCOLOR and PBM_SETBARCOLOR are supported in Windows 95+, but it took them until Vista to develop PBM_GETBKCOLOR and PBM_GETBARCOLOR??!! How do failures like that go overlooked for such a long period of time? Sounds like they have some lazy developers are Microsoft. The Pragmatic ProgrammerMay 31st, 2008
Anyways, I was reading today the section entitled “Programming by Coincidence” and here is an except:
One thing that I know is that in order to be a good programmer you have to be persistent when it comes to tracking down and fixing bugs. In the paragraph above, Fred spends several weeks working on code, but yet he gives up after several hours and calls it quits? Bugs can be fixed, if you spend enough time fixing them. The problem with Fred is that he is a script kiddy. He wants something for nothing and is not willing to work hard to fix his mistakes. Obviously he needs to spend a more significant amount of time trying to fix it, because given enough time, it can be done. I’ve spent days debugging and fixing bugs. Sounds to me like Fred is a wuss. There is another section called “Refactoring” that states that gardening is a better metaphor for software development than building construction because building construction doesn’t take into account refactoring.
The authors of the book got this one wrong because they didn’t fully evaluate the building construction metaphor. They imply that the building construction metaphor only includes the building’s initial construction and after it’s initial construction it has been built perfectly without flaw. While a lot of the work is complete after a building’s initial construction it does not mean that remodeling or reconstruction won’t take place further down the road, especially if their were errors in the building’s initial design. So the remodeling of the building, or the gutting of electrical or plumbing, does in fact take into account the refactoring aspect of programming. Because the authors only considered the building construction metaphor within a short timespan, they completely miss the fact that the building could be totally remodeled 20 years down the road — refactoring! Let me also say that I’ve never heard the word “development” from the term “software development” being used in conjunction with the work of a gardener. Maybe a landscape developer, but a landscape developer is more of an architect than a developer. Nevertheless if anybody wants to be a software developer that is liken to a gardener, that is completely your gay wish. But as for me, I rather my work to be likened to the construction of a building. Toward the end of the book, it tends to repeat itself, by trying to explain the same thing 10,000 different ways. Talk about DRY (Don’t Repeat Yourself)! The Old New ThingMay 31st, 2008
|