Notes from Daily Encounters with Technology RSS 2.0
 
# Saturday, June 03, 2006

Either as a user or as a developer you have certainly noticed that sometimes the application just flashes in the taskbar instead of actually coming to the foreground when the SetForegroundWindow function is called. What you might not know is why and when this happens.

As far as the why goes the Application Compatibility Toolkit’s Compatibility Administrator puts it very nicely in the GiveupForeground compatibility fix description: In Windows XP the foreground semantics have been changed to stop foreground focus stealing by one application if another application is active.

Further investigation reveals that this is related to the ForegroundLockTimeout value. It defines how much time must pass since the last user input to allow another process to force its window into the foreground. Before that time such a window only flashes in the task bar. The default value is 200000 milliseconds. The setting is stored in the registry:

HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout

The value can be programmatically changed by calling the SystemParametersInfo function as follows:

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

The downside is that the call only succeeds when the calling thread has permission to change the foreground window which usually isn’t the case.

To make the long story short: you should never depend on being able to bring your application window to the foreground and this will certainly only get more restrictive in the future. If the flashing in the taskbar is not enough, you should consider using tray balloon pop-ups as the alternative way of notifying the user.

Saturday, June 03, 2006 2:18:29 PM (Central European Daylight Time, UTC+02:00)  #    Comments [2] - Trackback
Development | Win32

By default the Windows XP Welcome screen shows the users created through the control panel applet. Administrator is shown only if it is the only account with administrative privileges. You can change all that by setting up the correct values in the registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList

To change the default behavior for a user create a DWORD value with its name identical to the account name and set its value to 1 to show it or to 0 to hide it.

Saturday, June 03, 2006 11:59:42 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Software | Windows

I really need to write down this information here so that I won’t be googling for it every time a friend or a coworker asks me about it. The default port number 3389 for RDP (Remote Desktop and Terminal Services) can be changed through the following registry value:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp\PortNumber

Saturday, June 03, 2006 11:37:49 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Software | Windows
# Sunday, May 28, 2006

Due to tightened default security in Windows 2003 the file shares cannot be accessed without logon in a domainless environment even if both shares and folders are set up to allow access to Everyone.

A bit of googling returns many different suggestions for solving the problem, none of which really seems to work for sure. I’m just adding my two cents to this confusion, hoping that this posting will help me the next I’ll be solving the same problem.

It’s all about configuring the Security options in Local Security policy. The logical path of enabling the Network Access: Let Everyone permissions apply to anonymous users policy and disabling the Network access: Restrict anonymous access to Named Pipes and Shares policy didn’t help. On the other hand enabling the Accounts: Guest account status policy and setting the Network access: Sharing and security model for local accounts policy to Guest only - local users authenticate as Guest did the trick. Don't forget to call gpupdate after changing the policy to enforce it immediately.

I’m not asserting that this is THE solution but it worked for me. However, you should be aware of the implications of enabling the guest account before doing it to solve your immediate problem.

A few additional words on the last mentioned policy change: It proves useful when the file server and the client have the same usernames defined but the passwords don’t match because it forces the client to login as guest. By default the client tries to login to the server with wrong password which once again causes the login prompt to appear. It is useful to keep the default setting when the password is the same because the auto login allows for granularity in security settings if more than equal permissions for everyone are needed.

Sunday, May 28, 2006 3:49:50 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Software | Windows

By switching from C# with P/Invoke calls to Managed C++ when implementing a managed wrapper for the ANSI C style library I stumbled upon, I wanted to avoid the tedious and error-prone task of writing the P/Invoke signatures for function calls and user-defined types for the structures they used. As a side result I also managed to avoid most of the advanced marshalling issues with complex data structures.

With simple value types not needing any explicit marshalling only strings need special attention since char* and System::String can’t be implicitly converted between. The Marshal class implements the methods necessary for doing this as demonstrated in the following snippet:

String^ MCPP::Together(String^ first, String^ second)
{
   // marshal managed strings to unamanged memory
   IntPtr firstPtr = Marshal::StringToHGlobalAnsi(first);
   IntPtr secondPtr = Marshal::StringToHGlobalAnsi(second);

   // cast unmanaged buffer to a characer array
   char* firstNative = static_cast<char*>(firstPtr.ToPointer());
   char* secondNative = static_cast<char*>(secondPtr.ToPointer());

   // perform some unmanaged calls
   int bufferSize = strlen(firstNative) + strlen(secondNative) + 4;
   char* resultBuffer = new char[bufferSize];
   sprintf_s(resultBuffer, bufferSize, "%s + %s", firstNative, secondNative);
  
   // marshal unmanaged character array to managed string
   String^ result = Marshal::PtrToStringAnsi(static_cast<IntPtr>(resultBuffer));
  
   // free all unmanaged buffers
   delete[] resultBuffer;
   Marshal::FreeHGlobal(firstPtr);
   Marshal::FreeHGlobal(secondPtr);
  
   // return managed string
   return result;
}

It should be noted that it wouldn’t make any sense switching to unmanaged code to do some string operations only as shown above. This is for demonstration purposes only and you would usually call some unmanaged libraries or the like instead of it. But it is a nice demonstration how cumbersome string operations were in C. If you were doing this once, the sprintf_s function call might have caught your attention. It’s a safe implementation of sprintf which prevents buffer overflows.

Another point worth mentioning is that you have to take care of allocated memory for the conversion since your character array is now allocated on the unmanaged heap. Make sure you use the FreeHGlobal method to do it, not the free (used for freeing memory allocated by *alloc calls – ANSI C style) or delete (used for freeing memory allocated by new calls – C++ style) functions.

To reduce the code overhead of string conversions between managed and unmanaged world you might consider wrapping it into a helper class. This should also help preventing unwanted memory leaks during the conversions.

Sunday, May 28, 2006 2:41:03 PM (Central European Daylight Time, UTC+02:00)  #    Comments [2] - Trackback
Development | .NET | C++ | Interop
Sponsored Ads

About Me

Damir Arh

Microsoft Certified Professional

View Damir Arh's profile on LinkedIn

Profile for ExAmigan

ExAmigan

Twitter
Damir's Corner: Avoiding Queue Starvation in CruiseControl.NET http://goo.gl/fb/G52YB 1 day ago
RT @aleksj: From http://last.fm/robots.txt: Disallow: /harming/humans, Disallow: /ignoring/human/orders, Disallow: /harm/to/self #asimov 2 days ago
Eagle Eye on DVD was a pleasant surprise. It passed under my radar when it was first released. 5 days ago
Multiple RTM gadgets in iGoogle suddenly can't show different lists anymore http://digs.by/aD5AbJ 6 days ago
Notifications for new projects in CCTray are a nice new feature of #ccnet 1.5 7 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2010, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)