Friday, January 1, 2010

學車

有兩間網上評語比較好既有 大昌 同 大聯,但係佢地都寫明要有兩年牌齡。
世紀租車 同 租車樂就唔限牌齡,但係網上無評語,唔知信唔信得過

Tuesday, September 1, 2009

Unicode use wstring

http://www.prashantmhatre.com/programming/what-is-wstring-discussion-on-wstring/

C++ Qamp;A
GetKeyState, the STL String Class, Exposing C++ Objects, and More
Paul DiLascia

Code download available at: CQA0408.exe (234 KB)
Browse the Code Online


Q I want users to hold down the Control key while double-clicking on my program's icon to have the program start up in a particular way. Neither ::GetCommandLine nor __argc give any indication that the key was pressed; nor does there seem to be any way to do this in MFC using CCommandLineInfo. Is there a way to find this out, say by polling the key?
Dean Jones


A Yes, it's very simple. All you have to do is call GetKeyState. This function returns the status of a virtual key at the time the current message you are processing was sent. The status can be up, down, or toggled. Toggled is for keys like Caps and Shift Lock, which alternate states. For ordinary keys like the Control key (VK_CONTROL), the high-order sign bit of the state is 1 if the key is down.
Many apps use Control+F8 as the special key to launch in restore mode. For example, if your app lets users customize their workspaces, starting with Control+F8 might restore the workspace to its factory default settings. Just make sure you ask the user to confirm first. Even better would be to save the customizations in separate INI files, so users have a chance of recovering them. In any case, to check for the Control key when your app starts, you'd write something like this: Copy Code
if (GetKeyState(VK_CONTROL)<0) {
// enter special mode
}

Figure 1 shows a snippet from a sample MFC app you can download from the link at the top of this article that displays a message box and beeps if the user presses Ctl+F8 while starting the app. If you just want to check for the Control key, leave out the test for VK_F8.
Figure 1 GetKeyState
Copy Code
////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
// CtlTest illustrates how to test for a special control-key combination
// when your program starts.

#include "StdAfx.h"
#include "MainFrm.h"
#include "StatLink.h"
#include "resource.h"

class CMyApp : public CWinApp {
public:
virtual BOOL InitInstance();
•••
} theApp;

BOOL CMyApp::InitInstance()
{
BOOL bCtl = GetKeyState(VK_CONTROL)<0;
BOOL bF8 = GetKeyState(VK_F8)<0;
if (bCtl && bF8) {
if (AfxMessageBox(_T("Enter special startup mode?"),
MB_YESNO)==IDYES)
// Enter special startup mode here.
MessageBeep(0);
}
•••
}



Q I use the Standard Template Library (STL) std::string class very often in my C++ programs, but I have a problem when it comes to Unicode. When using regular C-style strings I can use TCHAR and the _T macro to write code that compiles for either Unicode or ASCII, but I always find it difficult to get this ASCII/Unicode combination working with the STL string class. Do you have any suggestions?
Q I use the Standard Template Library (STL) std::string class very often in my C++ programs, but I have a problem when it comes to Unicode. When using regular C-style strings I can use TCHAR and the _T macro to write code that compiles for either Unicode or ASCII, but I always find it difficult to get this ASCII/Unicode combination working with the STL string class. Do you have any suggestions?
Naren J.


A Sure. It's easy, once you know how TCHAR and _T work. The basic idea is that TCHAR is either char or wchar_t, depending on the value of _UNICODE: Copy Code
// abridged from tchar.h
#ifdef _UNICODE
typedef wchar_t TCHAR;
#define __T(x) L ## x
#else
typedef char TCHAR;
#define __T(x) x
#endif

A Sure. It's easy, once you know how TCHAR and _T work. The basic idea is that TCHAR is either char or wchar_t, depending on the value of _UNICODE: Copy Code
// abridged from tchar.h
#ifdef _UNICODE
typedef wchar_t TCHAR;
#define __T(x) L ## x
#else
typedef char TCHAR;
#define __T(x) x
#endif

When you choose Unicode as the character set in your project settings, the compiler compiles with _UNICODE defined. If you select MBCS (Multi-Byte Character Sets), the compiler builds without _UNICODE. Everything hinges on the value of _UNICODE. Similarly, every Windows® API function that uses char pointers has an A (ASCII) and a W (Wide/Unicode) version, with the real version defined to one of these, based on the value of _UNICODE: Copy Code
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif

Likewise, there's _tprintf and _tscanf for printf and scanf. All the 't' versions use TCHARs instead of chars. So how can you apply all this to std::string? Easy. STL already has a wstring class that uses wide characters (defined in the file xstring). Both string and wstring are typedef-ed as template classes using basic_string, which lets you create a string class using any character type. Here's how STL defines string and wstring: Copy Code
// (from include/xstring)
typedef basic_string char_traits, allocator >
string;
typedef basic_string char_traits, allocator >
wstring;

The templates are parameterized by the underlying character type (char or wchar_t), so all you need for a TCHAR version is to mimic the definitions using TCHAR: Copy Code
typedef basic_string char_traits,
allocator >
tstring;

Now you have a tstring that's based on TCHAR—that is, either char or wchar_t, depending on the value of _UNICODE. I'm showing you this to point out how STL uses basic_string to implement strings based on any underlying character type. Defining a new typedef isn't the most efficient way to solve your problem. A better way is to simply #define tstring to either string or wstring, like so: Copy Code
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif

This is better because STL already defines string and wstring, so why use templates to create another string class that's the same as one of these, just to call it tstring? You can use #define to define tstring to string or wstring, which will save you from creating another template class (though compilers are getting so smart these days it wouldn't surprise me if the duplicate class were discarded).
In any case, once you have tstring, you can write code like this:
Copy Code
tstring s = _T("Hello, world");
_tprintf(_T("s =%s\n"), s.c_str());

The method basic_string::c_str returns a const pointer to the underlying character type; in this case, that character type is either const char* or const wchar_t* .
Figure 2 shows a simple program I wrote that illustrates tstring. It writes "Hello, world" to a file and reports how many bytes were written. I set the project up so it uses Unicode for the Debug build and MBCS for the Release build. You can compile both builds and run them to compare the results. Figure 3 shows a sample run.
Figure 2 tstring
Copy Code
////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//

// TSTRING shows how to implement a tstring class that uses STL string or
// wstrings depending on the setting of _UNICODE, similar to TCHAR,
// _tprintf and all the other "t" versions of functions in the C runtime.
//
// To see the difference, compile both debug and release versions. The
// debug version uses Unicode; the release uses MBCS. Then run each
// program and compare the output files.
//
#include "stdafx.h"
#include "resource.h"

using namespace std;

// tstring is either string or wstring, depending on _UNICODE.
// This works too, but may produce an extra class:
//
// typedef basic_string,
// allocator > tstring;
//
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif

static void WriteString(HANDLE f, LPCTSTR lpsz, int len);

void _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// process args
if (argc != 2) {
_tprintf(_T("Usage: tstring [filename]\n"));
_tprintf(_T(" writes test message to [filename]\n"));
return;
}

// CreateFile will create Unicode or MBCS string
// depending on value of _UNICODE.
LPCTSTR filename = argv[1];
HANDLE f = CreateFile(filename, ...);
if (f!=INVALID_HANDLE_VALUE)
{
if (GetFileType(f) == FILE_TYPE_DISK)
{
// create STL tstring
tstring s = _T("Hello, world");
WriteString(f, s.c_str(), s.length());
} else {
tprintf(_T("ERROR: the specified file '%s' is not a disk file\n"),
filename);
}
CloseHandle(f); // close file
} else {
_tprintf(_T("ERROR: can't open '%s'\n"), filename);
}
}

////////////////
// write string to file.
//
void WriteString(HANDLE f, LPCTSTR lpsz, int len)
{
DWORD nWrite = len * sizeof(TCHAR);
DWORD nActual;
if (WriteFile(f, lpsz, nWrite, &nActual, NULL)) {
// display results.
_tprintf(_T("%d bytes written\n sizeof(TCHAR)=%d\n"), nActual,
sizeof(TCHAR));
} else {
_tprintf(_T("ERROR %d writing\n"), GetLastError());
}
}


Figure 3 tstring in Action
By the way, MFC's CString is now married to ATL so that both MFC and ATL use the same string implementation. The combined implementation uses a template class called CStringT that works like STL's basic_string in the sense that it lets you create a CString class based on any underlying character type. The MFC include file afxstr.h defines three string types, like so: Copy Code
typedef ATL::CStringT StrTraitMFC> CStringW;
typedef ATL::CStringT StrTraitMFC> CStringA;
typedef ATL::CStringT StrTraitMFC> CString;
CStringW, CStringA, and CString are just what you would expect: wide, ASCII, and TCHAR versions of CString.
So which is better, STL or CStrings? Both classes are fine, and you should use whichever you like best. One issue to consider is which libraries you want to link with and whether you're already using ATL/MFC or not. From a coding perspective, I prefer CString for two features. First, you can initialize a CString from either wide or char strings: Copy Code
CString s1 = "foo";
CString s2 = _T("bar");

Both initializations work because CString silently performs whatever conversions are necessary. With STL strings, you can't initialize a tstring without using _T() because you can't initialize a wstring from a char* or vice versa. The other feature I like about CString is its automatic conversion operator to LPCTSTR, which lets you write the following: Copy Code
CString s;
LPCTSTR lpsz = s;
With STL, on the other hand, you have to explicitly call c_str. This is really nit-picking and some would even argue it's better to know when you're performing a conversion. For example, CStrings can get you in trouble with functions that use C-style variable arguments (varargs), such as printf: Copy Code
printf("s=%s\n", s); // Error: thinks s is char*
printf("s=%s\n", (LPCTSTR)s); // required

Without the cast you can get garbage results because printf expects s to be char*. I'm sure many readers have made this error. Preventing this sort of mishap is no doubt one reason the designers of STL chose not to provide a conversion operator, insisting instead that you invoke c_str. In general, the STL folks tend to be a little more academic and purist types, whereas the Redmontonians are a little more practical and loosey-goosey. Hey, whatever. The practical differences between std::string and CString are slim.


Q I'm trying to expose my C++ library to C# and the .NET Framework using managed extensions and interop. One of my classes has a union in it, but .NET doesn't seem to like that: Copy Code
class MyClass {
union {
int i;
double d;
};
};

Q I'm trying to expose my C++ library to C# and the .NET Framework using managed extensions and interop. One of my classes has a union in it, but .NET doesn't seem to like that: Copy Code
class MyClass {
union {
int i;
double d;
};
};

The point of the union is to save space because I know the int and double are never used at the same time. Also, I have a lot of code that already references the union, and I prefer not to change it. How can I expose this class to .NET-compliant languages? Do I have to make each value in the union a separate member, or use methods instead?
John Bunt


A You could take either of those approaches, but you don't have to. In .NET interop, there's always a way to expose your C++ objects—well, almost always. The common language runtime (CLR) doesn't understand unions, but you can use an ordinary __value struct with some special voodoo to tell it where your members go. The magic attributes are StructLayout and FieldOffset. In managed C++, it looks like this: Copy Code
[StructLayout(LayoutKind::Explicit)]
public __value struct MyUnion {
[FieldOffset(0)] int i;
[FieldOffset(0)] double d;
};
This tells the CLR that the integer i and the double d are both at offset zero (that is, the first items) in your struct, which makes them overlap and, in effect, the struct is a union. You can then use MyUnion in your __gc class, like so: Copy Code
public __gc class CUnionClass {
public:
// can access this directly because it's public
MyUnion uval;
};

A You could take either of those approaches, but you don't have to. In .NET interop, there's always a way to expose your C++ objects—well, almost always. The common language runtime (CLR) doesn't understand unions, but you can use an ordinary __value struct with some special voodoo to tell it where your members go. The magic attributes are StructLayout and FieldOffset. In managed C++, it looks like this: Copy Code
[StructLayout(LayoutKind::Explicit)]
public __value struct MyUnion {
[FieldOffset(0)] int i;
[FieldOffset(0)] double d;
};
This tells the CLR that the integer i and the double d are both at offset zero (that is, the first items) in your struct, which makes them overlap and, in effect, the struct is a union. You can then use MyUnion in your __gc class, like so: Copy Code
public __gc class CUnionClass {
public:
// can access this directly because it's public
MyUnion uval;
};

With CUnionClass defined, you can access the members i and d directly through uval from any .NET-compliant language. In C# it looks like the following code snippet: Copy Code
CUnionClass obj = new CUnionClass();
obj.uval.i = 17;
obj.uval.d = 3.14159

I wrote all this up in a little program Called MCUnion that implements a managed C++ library with a CUnionClass like the one shown earlier, and a C# program utest that tests it (see Figure 4 and Figure 5). CUnionClass shows how to add properties for the union members, so you can access the values using obj.i and obj.d instead of obj.uval.i and obj.uval.d. This may or may not be what you want, depending on your design. If you like, you could make uval private/protected, so clients must use the properties. This would completely hide the union nature of uval. The test program accesses i and d both ways—through the union (uval) itself and through the properties i and d.
Figure 5 C-Style Unions
Copy Code
////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//

// This module shows how to export a C-style union as a managed __value
// struct using StructLayout and FieldOffset. To compile this program and
// the C# test program that uses it, cd to this directory and type
//
// NMAKE
//
#using

using namespace System;
using namespace System::Runtime::InteropServices;

// Handy definitions to save typing ugly __'s.
#define DOTNET __gc
#define PROPERTY __property
#define VALUE __value

namespace MCLib {

//////////////////
// Here's a typical C/C++ union:
//
// union {
// int i;
// double d;
// };
//
// And here's how to implement it for consumption by .NET:
//
[StructLayout(LayoutKind::Explicit)]
public VALUE struct MyUnion {
[FieldOffset(0)] int i;
[FieldOffset(0)] double d;
};

// This exported class contains the union as a member.
// The C# program test.cs shows how to use it.
//
public DOTNET class CUnionClass {
public:
// can access this directly because it's public
MyUnion uval;

// additional access through properties
PROPERTY int get_i() { return uval.i; }
PROPERTY void set_i(int i) { uval.i = i; }

PROPERTY double get_d() { return uval.d; }
PROPERTY void set_d(double d) { uval.d = d; }
};

}

Figure 4 utest
Copy Code
////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
// This C# program tests the union defined in MCLib.cpp.
//
using System;
using MCLib; // home-brew MC++ class lib

class MyApp {
// main entry point
[STAThread]
static int Main(string[] args) {
CUnionClass obj = new CUnionClass();

// Note that this code accesses the embedded union both directly
// through obj.val and indirectly through the properties i and d.
obj.uval.i = 17;
Console.WriteLine("Set i=17:");
Console.WriteLine(" i={0}", obj.i);
Console.WriteLine(" d={0}", obj.d);

obj.uval.d = 3.14159;
Console.WriteLine();
Console.WriteLine("Set d=3.14159:");
Console.WriteLine(" i={0}", obj.i);
Console.WriteLine(" d={0}", obj.d);
return 0;
}
}



Q I'm writing a DirectX® screen saver and need to obtain a list of JPG, BMP, GIF, and TGA files from the user's My Pictures directory as a default before they learn where the screen saver settings are and can load them on their own. I have no problem setting the image textures into DirectX, but I'm afraid the My Pictures directory will be different for each user. On my machine it's "C:\Documents and Settings\Administrator\My Documents\My Pictures". Is there a simple way to get the location of my pictures?
Q I'm writing a DirectX® screen saver and need to obtain a list of JPG, BMP, GIF, and TGA files from the user's My Pictures directory as a default before they learn where the screen saver settings are and can load them on their own. I have no problem setting the image textures into DirectX, but I'm afraid the My Pictures directory will be different for each user. On my machine it's "C:\Documents and Settings\Administrator\My Documents\My Pictures". Is there a simple way to get the location of my pictures?
Bruce MacFarlane


A Indeed, there is. The function you want is SHGetSpecialFolderPath, which gets the location of a special folder using a predefined ID like CSIDL_MYPICTURES, defined in ShlObj.h along with a bunch of other shell stuff. For example: Copy Code
TCHAR buf[MAX_PATH];
SHGetSpecialFolderPath(NULL, // HWND
buf,
CSIDL_MYPICTURES,
NULL); // don't create

A Indeed, there is. The function you want is SHGetSpecialFolderPath, which gets the location of a special folder using a predefined ID like CSIDL_MYPICTURES, defined in ShlObj.h along with a bunch of other shell stuff. For example: Copy Code
TCHAR buf[MAX_PATH];
SHGetSpecialFolderPath(NULL, // HWND
buf,
CSIDL_MYPICTURES,
NULL); // don't create

You should always use SHGetSpecialFolderPath to get the path name of a special folder (as opposed to probing the registry directly) because it's guaranteed to work across all versions of Windows, including future ones even if the Redmondtonians ever decide to change the registry keys where the special folder path names are stored. For Windows 2000 and Windows XP, SHGetSpecialFolderPath lives in shell32.dll. Older versions of Windows such as Windows 9x and Windows NT® don't have SHGetSpecialFolderPath, but Microsoft provides it in a special DLL, SHFOLDER.DLL, which you're free to distribute with your app.
In fact, the official documentation from Redmond says, "Software vendors are encouraged to redistribute [SHFOLDER.DLL] as much as possible to enable this support on Windows operating systems prior to Windows 2000." The only catch is if you're targeting older versions of the Windows operating system, but building on Windows 2000 or Windows XP, you must explicitly link with SHFOLDER.DLL; otherwise the linker will grab SHGetSpecialFolderPath from Shell32.dll.
Since this is a C++ column, I wrote a little class called CSpecialFolder (see Figure 6) that's derived from CString and automatically calls SHGetSpecialFolderPath. To use it, all you have to write is: Copy Code
CSpecialFolder mypics(CSIDL_MYPICTURES);
LPCTSTR lpszPath = mypics;

Figure 6 CSpecialFolder
Copy Code
////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//

// Class to get the path name of a special folder. To use:
//
// CSpecialFolder sf(CSIDL_MYPICTURES)
//
// Now the string holds the path name.
//
class CSpecialFolder : public CString
{
protected:
BOOL GetSpecialFolder(int nFolder) {
Empty();
BOOL bRet = SHGetSpecialFolderPath(NULL, GetBuffer(MAX_PATH),
nFolder, FALSE);
ReleaseBuffer();
return bRet;
}

public:
CSpecialFolder(int nFolder) {
GetSpecialFolder(nFolder);
}
CSpecialFolder& operator=(int nFolder) {
GetSpecialFolder(nFolder);
}
};

The assignment works because CSpecialFolder is derived from CString, which has an implicit conversion operator to LPCTSTR. CSpecialFolder is available in the download, along with a test program that displays the path names of all the special folders that have CSIDL_XXX IDs defined in ShlObj.h. This includes familiar folders like Favorites, Fonts, Programs, History, and AppData—as well as some strange ones like CSIDL_BITBUCKET (Recycle Bin), CSIDL_INTERNET (path to Microsoft® Internet Explorer icon, I believe), and CSIDL_SYSTEMX86 (x86 system directory on RISC/Alpha systems for Windows 2000).


Send your questions and comments for Paul to cppqa@microsoft.com.



Paul DiLascia is a freelance writer, consultant, and Web/UI designer-at-large. He is the author of Windows++: Writing Reusable Windows Code in C++ (Addison-Wesley, 1992). Paul can be reached at http://www.dilascia.com.

Friday, August 28, 2009

Visual C++ Tips and Tricks

http://www.catch22.net/tuts/vctips

This section presents a collection of Visual C++ 6.0 tips which are often hard to find information about. All of the tips are useful in their own way, and many will work exactly as-is in Visual Studio .NET also, so take a moment to browse through the collection.

1. Debug build works, Release build doesn't ??
This is the single most common posting made to programming forums and usenet. The answer is simple - fix the bug in your code!!! The reason you are experiencing problems is usually due to uninitialized variables in functions or classes. Problems like this are present in both Debug and Release builds, but typically only manifest themselves in the release binary because the debug build is alot more tolerant to errors.

2. Fix Intellisense problems
This is the most frustrating "feature" of Visual Studio - when intellisense stops working. Simply exit Visual Studio and browse to your project directory - then delete the .ncb file for your project. When you restart Visual Studio the problem will be fixed.

3. Auto-indent current selection
Press Alt+F8 on any highlighted text in the code-editor, and the code will be automatically adjusted so that each line is at the correct indentation level. Selecting an entire function body properly indents each line within the function.

4. Define custom keywords
Visual C++ has the ability to highlight user-defined keywords in your code. The colour of these user-defined keywords is easily adjusted using the Options dialog, but adding user-defined keywords is not documented.

Simply create a file called "usertype.dat" in your C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin directory (the same directory that contains MSDEV.EXE). The contents of this file is a series of custom keywords, each one on a separate line. These keywords do not need to contain the built-in types such as int, char etc - only additional keywords that you want highlighted.

Here is the usertype.dat I use on my development machine. This same tip applies to Visual Studio.NET - look in the C:\Program Files\Visual Studio.NET\Common7\IDE directory (where DEVENV.EXE lives) and place your usertype.dat file there.

5. Define custom colours in the IDE
The Visual C++ IDE only allows you to select from 16 different colours. If you are fussy about the these colours then you can modify the base 16 colours from the following registry location:

HKCU\Software\Microsoft\Devstudio\6.0\Format\Source Window\Inside this key there are a series of binary data items, one for each user-definable entity in the source window - such as comments, keywords, strings and normal text. Each value is made up using the same format. The first four bytes are the foreground colour, in RGBA format (3 bytes for RGB and 1 byte for padding). The background colour follows immediately afterwards using the same format:

[ RR GG BB xx ][ RR GG BB xx ]
Foreground BackgroundYou can use the Registry Editor to Export and Import your colour settings from machine-to-machine.

6. Column-based selection
The Visual studio editor lets you select text in a line-by-line manner. However, holding the ALT key down whilst making a selection with the mouse causes columns of text to be selected rather than rows (lines).s

7. View structure members
Position the cusor next to the same of a structure variable and press CTRL+SPACE. The structure members popup window will appear.

8. View function parameters
Position the cursor on/after the name of a function and press CTRL+SHIFT+SPACE. The function-parameters popup window will appear.

9. Display Disassembly
Whilst debugging a project, press ALT+8 to switch to assembler mode.

10. Find Definition of any identifier
Right-click the mouse on any variable, function, structure or macro. A popup menu will appear - select "Goto Definition Of". Usually an error box will appear stating that you need to rebuild your project with browse information. Click YES, and wait for the project to rebuild. Now when you "Goto Definition Of", Visual C++ will open the appropriate source / header file and jump to the line containing the definition of the item you just selected.

11. Bookmark lines of text
You can bookmark lines of text for further reference, using the "Mark" commands. Press Ctrl+F2 to mark/unmark a line of text. Press F2 to skip between marked positions within each source-file.

The list of current bookmarks can be displayed by the Edit -> Bookmarks dialog or by pressing ALT+F2.

12. Callgraphs
Position the cursor over any function name and hit ALT+F12. If your project was built with browse-information, a dialog will appear asking what you want to do. Select CallGraph to view a hierarchy of all sub-functions which are called by your function. This is a very useful feature often overlooked in Visual Studio.

13. Navigate around your source quickly
Hold down Control whilst using the Arrow Keys to make the cursor skip between words, rather than moving character-by-character.

14. Find corresponding brackets
Position the cursor over any "{", "[", "(", "}", "]" or ")" bracket and hit CTRL+"]". The cursor will move to the corresponding opening/closing bracket of that expression.

15. Show/Hide whitespace
Press CTRL+SHIFT+8 to show / hide whitespace markers.

16. Open header files
Right-click any filename in your source-code (i.e. in a string expression or #include line) and click "Open Document". Visual Studio will open the corresponding file in the IDE.

17. Installing Platform SDK
The simplest method to install a new SDK or DDK is to install the entire package to a new location on your hard-disk (rather than install over the old one). I always recommend storing SDKs and MSDN help libraries in a "simple" directory location so it is easy to browse to using the command-prompt. i.e.

C:\MSVS\SDK2004\
C:\MSVS\MSDN2004\

When you want to integrate this new SDK into Visual C++, bring up the Tools->Options dialog box, and select the "Directories" tab. There is a drop-down list which lets you entire directories for Include files (*.h) and Library files (*.lib). Enter a new directory location for the following paths and move them to the top of their respective lists:

C:\MSVS\SDK2004\Include
C:\MSVS\SDK2004\Lib

When Visual C++ compiles your project, it first searches the specified directories for include and library files. By putting the new directories at the top of the list it searches those first, before resorting to the "default" locations.

18. Preserve Keyboard and Layout settings
Visual Studio's keyboard and layout settings are stored in the following locations:

HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Keyboard
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\LayoutUse REGEDIT to Export these registry locations to an external file, then simply Import the settings when you need them on any new machine.

19. Using MAP files
You can see exactly what functions and global variables have been compiled into your project by looking at the corresponding MAP file in your /Debug or /Release directory. To enable this feature, open the Project->Settings dialog and select the "Linker" tab. Make sure the "Generate Map File" checkbox is selected.

20. Generate assembly-language output
You can see the full assembly language output of your project (complete with corresponding source-line and op-code output). Open the Project->Settings dialog and select the "C/C++" tab. Select the "Listing Files" option from the drop-down list and then select what type of output you want. The resulting file is generated in your /Debug or /Release directory.

21. Tiny Executables!
Generate instantly smaller executables by performing the following steps:

Open the Project Settings dialog from the Project menu.
Select the C/C++ tab
Select Code Generation from the Category combo-box.
In the Use run-time library drop-down-list, select:
Debug Multithreaded DLL for Debug builds
Multithreaded DLL for Release builds

Now add the following line to the top of your main source file and you will have instantly smaller exes:

#pragma comment(linker, "/OPT:NOWIN98")22. Breakpoints Dialog
It is very easy to miss the Breakpoints dialog from the Edit menu (what a strange place to put it!).

However some very powerful debugging can be achieved. Set breakpoints when specific variables change in value, when a Window procedure is called with a certain window-message, or when other conditions are met.

23. Edit Executable Resources
Visual Studio is a fully functional binary resource editor. Simply open an executable or dll using the File->Open dialog, but before pressing OK, select the "Resources" option in the "Open As" drop-down-list. You can use this feature to edit menus, dialogs, strings and bitmaps in regular executables and dlls such as notepad, paint, wordpad etc.

24. Display Workspace window
Press Alt+0 (Alt+zero) at any time to bring up the Project Workspace window.

25. Debug Release Builds
It is possible (and usually desirable) to generate debug information for your release builds. This is advantageous because you can now debug problems that only manifest themselves in a release-build environment. You can do this in such a way that the debug information is not stored inside the executable (thus bloating it up) - instead, it is stored in a separate .pdb (program database) file. The only entry in the executable is a small string which directs the debugger to your program database, so you can distribute the executable without this sensitive information.

Select "Link" from the Project->Settings dialog, and then select "Debug" from the Category drop-down list. Make sure that the "Debug Info" checkbox is selected, and then enable "COFF Format".

Now for any source-file that you want debugging information generated for, select that file (or your entire project) in the Project->Settings dialog, and then make sure that the "Program Database" option is enabled in the C/C++ General-settings tab.

26. Warning Level 4
Catch more errors in your project by enabling "Warning Level 4" in the C/C++ General settings tab.

27. Console and Window applications
You can switch between Console and Win32 applications at any time by editing the Linker options manually in the "Project Options" edit-field under the Project->Settings->Link dialog. Edit the /SUBSYSTEM option to switch between console and gui builds. i.e.

/SUBSYSTEM:CONSOLE

/SUBSYSTEM:WINDOWS

28. Generate Browse Information
Select Generate Browse Info under the C/C++ project settings tab, for any source-files that you want to be included. This is very useful for searching for function definitions and declarations - just right-click a function / variable and select "Goto Definition Of..." and the IDE will take you straight there.

29. Visual Studio Debugger - Watch Window
There are many useful commands available in the watch window, which can alter the way variables and error values are displayed by the debugger.



Command Description
eax Displays the return value of a function after it returns.
@err Display the current Win32 GetLastError value
string,su Display the specified string as Unicode.
value,hr Treat the specified value as a HRESULT and display it's string representation
value,wm Decode the specified value as a Windows Message.
value,x Display value in Hexadecimal
array,23 Display exactly 23 elements of the specified array
address,mb Display the specified address/variable as a memory-block hex-dump.

30. Avoid stepping into CRT functions
The reason the Visual Studio debugger steps into CRT functions (i.e. into new/delete) when you don't want it to, is because you installed the source-code to the CRT/MFC libraries. Either move the source-code to a different location, or prevent the Visual Studio debugger from stepping into specific functions (whilst pressing F11) by performing the following steps:

Open AUTOEXP.DAT (from the COMMON\MSDEV98\BIN\ directory)
Add a section called [ExecutionControl]
Add a line in this section with the following format:
functionName=NoStepIntoclassName::*=NoStepInto

Restart the IDE for the changes to take effect.
Of course as soon as you accidently step into a function that you didn't want to be in, simply press SHIFT+F11 to step out again.

Wednesday, August 5, 2009

Solving 11 Likely Problems In Your Multithreaded Code

http://msdn.microsoft.com/en-us/magazine/cc817398.aspx

Multithreaded Code
Joe Duffy

This article discusses:
Fundamental concurrency concepts
Concurrency problems and mitigations
Patterns for achieving safety
Cross-cutting concepts
This article uses the following technologies:
Multithreading, .NET Framework


Contents
Data Races
Forgotten Synchronization
Incorrect Granularity
Read and Write Tearing
Lock-Free Reordering
Reentrancy
Deadlocks
Lock Convoys
Stampeding
Two-Step Dance
Priority Inversion
Patterns for Achieving Safety
Immutability
Purity
Isolation

Concurrency is everywhere. Server-side programs have long had to deal with a fundamentally concurrent programming model, and as multicore processors become more commonplace, client-side programs will have to as well. Along with the addition of concurrency comes the responsibility for ensuring safety. In other words, programs must continue to achieve the same level of robustness and reliability in the face of large amounts of logical concurrency and ever-changing degrees of physical hardware parallelism.
Correctly engineered concurrent code must live by an extra set of rules when compared to its sequential counterpart. Reads and writes from memory and access to shared resources need to be regulated using synchronization so that conflicts do not arise. Additionally, it often becomes necessary for threads to coordinate to get a certain job done.
As a direct result of these additional requirements, it becomes nontrivial to ensure that threads are continually making consistent and adequate forward progress. Synchronization and coordination deeply depend on timing, which is nondeterministic and hard to predict and test for.
What makes these attributes difficult is simply that it requires a mindset shift. There isn't a single API that you can learn or a snippet of code to copy and paste. There really is a fundamental set of concepts that you need to learn and become comfortable with. It's likely that certain languages and libraries can hide some concepts over time, but if you're doing concurrency today, you won't have that luxury. This article describes some of the more common challenges to be aware of and presents advice for coping with them in your software.
I'll start by looking at the kinds of things that often go wrong in concurrent programs. I call these "safety hazards" because they are so easy to stumble upon and because their consequences are typically quite undesirable. These hazards cause your programs to break by either crashing or corrupting memory.


A data race—or race condition—occurs when data is accessed concurrently from multiple threads. Specifically, it happens when one or more threads are writing a piece of data while one or more threads are also reading that piece of data. This problem arises because Windows programs (in C++ and the Microsoft .NET Framework alike) are fundamentally based on the concept of shared memory, where all threads in a process may access data residing in the same virtual address space. Static variables and heap allocation can be used to share.
Consider this canonical example:
Copy Code
static class Counter {
internal static int s_curr = 0;
internal static int GetNext() {
return s_curr++;
}
}

The goal of Counter is presumably to hand out a new unique number for each call to GetNext. If two threads in the program both call GetNext simultaneously, however, two threads might be given the same number. The reason is that s_curr++ compiles into three separate steps:
Read the current value from the shared s_curr variable into a processor register.
Increment that register.
Write the register value back to the shared s_curr variable.
Two threads executing this same sequence can both read the same value from s_curr locally (say, 42), increment it (to, say, 43), and publish the same resulting value. GetNext thus returns the same number for both threads, breaking the algorithm. Although the simple statement s_curr++ appears to be atomic, this couldn't be farther from the truth.


Forgotten Synchronization
This is the simplest kind of data race: synchronization is forgotten altogether. Races of this kind can be, in rare situations, benign, meaning that they are correct, but most are fundamental problems of correctness.
Problems like this aren't always so obvious. For example, an object may be part of some large complicated object graph that happens to be reachable from a static variable or became shared by passing an object as part of a closure when creating a new thread or queuing work to a thread pool.
It is imperative to pay attention to when an object (graph) trans­itions from private to shared. This is called publication and will be discussed later in the context of isolation. The reverse is called privatization—that is, when an object (graph) goes from being shared to private again.
The solution is to add proper synchronization. In the example of the counter, I could use a simple interlocked:
Copy Code
static class Counter {
internal static volatile int s_curr = 0;
internal static int GetNext() {
return Interlocked.Increment(ref s_curr);
}
}

This works because the update is confined to a single memory location, and because (conveniently) there is a hardware instruction (LOCK INC) that is equivalent to the software statement I'm trying to make atomic.
Alternatively, I could use a full-fledged lock:
Copy Code
static class Counter {
internal static int s_curr = 0;
private static object s_currLock = new object();
internal static int GetNext() {
lock (s_currLock) {
return s_curr++;
}
}
}

The lock statement ensures mutual exclusion among all threads trying to access GetNext, and uses the CLR System.Threading.Monitor class. C++ programs would use a CRITICAL_SECTION for the same purpose. There is no need to go with a lock for this particular example, but when multiple operations are involved it's seldom possible to fold them into a single interlocked operation.


Incorrect Granularity
Even if access to shared state occurs with proper synchronization, the resulting behavior may still be incorrect. The granularity must be sufficiently large that the operations that must be seen as atomic are encapsulated within the region. There is a tension between correctness and making the region smaller, because smaller regions reduce the time that other threads will have to wait to concurrently enter.
For example, take a look at the bank account abstraction shown in Figure 1. All is well, and the object's two methods, Deposit and Withdraw, appear to be concurrency-safe. Some banking application can use them without worry that balances will become corrupt due to concurrent access.
Figure 1 A Bank Account
Copy Code
class BankAccount {
private decimal m_balance = 0.0M;
private object m_balanceLock = new object();
internal void Deposit(decimal delta) {
lock (m_balanceLock) { m_balance += delta; }
}
internal void Withdraw(decimal delta) {
lock (m_balanceLock) {
if (m_balance < delta)
throw new Exception("Insufficient funds");
m_balance -= delta;
}
}
}

What if, however, you'd like to add a Transfer method? A naive (and incorrect) attempt would assume that, because Deposit and Withdraw are safe in isolation, they can be combined easily:
Copy Code
class BankAccount {
internal static void Transfer(
BankAccount a, BankAccount b, decimal delta) {
Withdraw(a, delta);
Deposit(b, delta);
}
// As before
}

This is incorrect. There is actually a period of time between the Withdraw and Deposit calls where the money is missing completely.
A correct implementation would need to acquire the locks on both a and b up front and then make the method calls:
Copy Code
class BankAccount {
internal static void Transfer(
BankAccount a, BankAccount b, decimal delta) {
lock (a.m_balanceLock) {
lock (b.m_balanceLock) {
Withdraw(a, delta);
Deposit(b, delta);
}
}
}
// As before
}

It turns out that this approach, while solving the granularity problem, is prone to deadlock. You'll see how to fix it later on.


Read and Write Tearing
As mentioned earlier, benign races allow you to access variables without synchronization. Reads and writes of aligned, naturally sized words—for example, pointer-sized things that are 32 bits (4 bytes) on 32-bit processors and 64 bits (8 bytes) on 64-bit processors—are atomic. If a thread is just reading a single variable that some other thread will write, and there aren't any complex invariants involved, you can sometimes skip the synchronization altogether thanks to this guarantee.
But beware. If you try this on a misaligned memory location, or a location that isn't naturally sized, you can encounter a read or write tearing. Tearing occurs because reading or writing such locations actually involves multiple physical memory operations. Concurrent updates can happen in between these, potentially causing the resultant value to be some blend of the before and after values.
As an example, imagine ThreadA sits in a loop and writes only 0x0L and 0xaaaabbbbccccddddL to a 64-bit variable s_x. ThreadB sits in a loop reading it (see Figure 2).
Figure 2 Tearing about to Happen
Copy Code
internal static volatile long s_x;
void ThreadA() {
int i = 0;
while (true) {
s_x = (i & 1) == 0 ? 0x0L : 0xaaaabbbbccccddddL;
i++;
}
}
void ThreadB() {
while (true) {
long x = s_x;
Debug.Assert(x == 0x0L || x == 0xaaaabbbbccccddddL);
}
}

You may be surprised to discover that ThreadB's assert might fire. The reason is that ThreadA's write will consist of two parts, the high 32-bits and the low 32-bits, in some order depending on the compiler. The same goes for ThreadB's read. Thus ThreadB could witness values 0xaaaabbbb00000000L or 0x00000000aaaabbbbL.


Lock-Free Reordering
Sometimes it's tempting to write lock-free code as a way of achieving better scalability and reliability. Doing so requires a deep understanding of the memory model of your target platform (see Vance Morrison's article "Memory Models: Understand the Impact of Low-Lock Techniques in Multithreaded Apps" at msdn.microsoft.com/magazine/cc163715 for details). Failure to understand and heed these rules can lead to memory reordering bugs. These happen because compilers and processors are free to reorder memory operations during the process or making optimizations.
As an example, assume s_x and s_y are both initialized to the value 0, as you see here:
Copy Code
internal static volatile int s_x = 0;
internal static volatile int s_xa = 0;
internal static volatile int s_y = 0;
internal static volatile int s_ya = 0;

void ThreadA() {
s_x = 1;
s_ya = s_y;
}

void ThreadB() {
s_y = 1;
s_xa = s_x;
}

Is it possible that, after ThreadA and ThreadB both run to completion, both s_ya and s_xa will contain the value 0? This seems ridiculous on its face. Either s_x = 1 or s_y = 1 will happen first, in which case the other thread will witness the update when it gets around to its update. Or so the theory goes.
Unfortunately, processors are free to reorder this code so that the loads effectively happen before the writes. You can get around this with an explicit memory barrier:
Copy Code
void ThreadA() {
s_x = 1;
Thread.MemoryBarrier();
s_ya = s_y;
}

The .NET Framework offers this particular API, and C++ offers _MemoryBarrier and similar macros. But the moral of the story is not that you should insert memory barriers all over the place. The moral is that you should steer clear of lock-free code until you've mastered memory models, and even then tread with care.


In Windows, including Win32 and the .NET Framework, most locks support recursive acquires. That just means that, if the current thread already holds a lock and tries to acquire it again, the request will be satisfied. This makes it easier to compose bigger atomic operations out of smaller ones. In fact, the BankAccount example shown earlier depended on recursive acquires: Transfer called both Withdraw and Deposit, each of which redundantly acquired a lock that Transfer had already acquired.
This can be the source of problems, however, if you end up in a situation where a recursive acquire occurs when you didn't expect it to. This can happen as a result of reentrancy, which is possible due to either explicit callouts to dynamic code (such as virtual methods and delegates) or because of implicitly reentered code (such as STA message pumping and asynchronous procedure calls). For this reason, among others, it's a good idea to never make a call to a dynamic method from within a lock region.
For example, imagine some method that breaks invariants temporarily and then calls a delegate:
Copy Code
class C {
private int m_x = 0;
private object m_xLock = new object();
private Action m_action = ...;

internal void M() {
lock (m_xLock) {
m_x++;
try { m_action(); }
finally {
Debug.Assert(m_x == 1);
m_x--;
}
}
}
}

C's method M ensures that m_x does not change. But there is a brief period of time where m_x is incremented by one before being decremented again. The callout to m_action looks innocent enough. Unfortunately, if it was a delegate accepted from users of the C class, it represents arbitrary code that can do anything it pleases. That includes calling back into the same instance's M method. And if that happens, the assert within the finally is apt to fire; there could be multiple calls to M active on the same stack, even though you didn't do it directly, which clearly can lead to m_x holding a value greater than 1.


When multiple threads encounter a deadlock, the system simply stops responding. Several MSDN Magazine articles have described how deadlocks occur and some ways of tolerating them—including my own article, "No More Hangs: Advanced Techniques to Avoid and Detect Deadlocks in .NET Apps," at msdn.microsoft.com/magazine/cc163618, and Stephen Toub's October 2007 .NET Matters column at msdn.microsoft.com/magazine/cc163352—so the discussion here will be kept light. In summary, whenever a circular wait chain is created—such that some ThreadA is waiting for a resource held by ThreadB, which is also reflexively waiting for a resource held by ThreadA (perhaps indirectly by waiting for a third ThreadC or more)—it is possible for all forward progress to come to a grinding halt.
A common source of this problem is with mutually exclusive locks. In fact, the BankAccount example shown earlier suffers from this problem. If ThreadA tries to transfer $500 from account #1234 to account #5678 at the same time ThreadB tries to transfer $500 from #5678 to #1234, the code can deadlock.
Using a consistent acquisition order can avoid the deadlock, as shown in Figure 3. This logic can be generalized to something called simultaneous lock acquisition, whereby multiple lockable objects are sorted dynamically according to some ordering among locks, so that any place two locks must be held at the same time they are acquired in a consistent order. Another scheme called lock leveling can be used to reject lock acquisitions that are provably done in an inconsistent order.
Figure 3 Consistent Acquisition Order
Copy Code
class BankAccount {
private int m_id; // Unique bank account ID.
internal static void Transfer(
BankAccount a, BankAccount b, decimal delta) {
if (a.m_id < b.m_id) {
Monitor.Enter(a.m_balanceLock); // A first
Monitor.Enter(b.m_balanceLock); // ...and then B
} else {
Monitor.Enter(b.m_balanceLock); // B first
Monitor.Enter(a.m_balanceLock); // ...and then A
}
try {
Withdraw(a, delta);
Deposit(b, delta);
} finally {
Monitor.Exit(a.m_balanceLock);
Monitor.Exit(b.m_balanceLock);
}
}
// As before ...
}

But locks are not the only source of deadlock. Missed wake-ups are another phenomenon, where some event is missed and a thread sleeps forever. This is common with synchronization events like Win32 auto-reset and manual-reset events, CONDITION_VARIABLEs, and CLR Monitor.Wait, Pulse, and PulseAll calls. A missed wake-up is usually a sign of improper synchronization, failure to retest a wait condition, or use of a wake-single primitive (WakeConditionVariable or Monitor.Pulse) when a wake-all (WakeAllConditionVariable or Monitor.PulseAll) would have been more appropriate.
Another common source of this problem is lost signals with auto- and manual-reset events. Because such an event can only be in one state—signaled or nonsignaled—redundant calls to set the event will effectively be ignored. If code assumes that two calls to set always translates to two threads awakened, the result can be a missed wake-up.


Lock Convoys
When the arrival rate at a lock is consistently high compared to its lock acquisition rate, a lock convoy may result. In the extreme, there are more threads waiting at a lock than can be serviced, leading to a catastrophe. This is more common on server-side programs where certain locks protecting data structures needed by most clients can get unusually hot.
For example, imagine this scenario: On average, eight requests arrive per 100 milliseconds. We use eight threads to service requests (because we're on an 8-CPU machine). Each of those eight threads must acquire a lock and hold it for 20 milliseconds before it can do meaningful work.
Unfortunately, access to this lock must be serialized, so it takes 160 milliseconds for all eight threads to enter and leave the lock. After the first exists, there will be 140 milliseconds of time before a ninth thread can access the lock. This scheme inherently will not scale, and there will be a continuously growing backup of requests. Over time, if the arrival rate does not decrease, client requests are apt to begin timing out, and a disaster will ensue.
Fairness in locks is known to contribute to convoys. The reason is that periods of time where the lock could have been made available are artificially blocked out, so that threads arriving must wait until the chosen lock owner thread can wake up, context switch, and acquire and release the lock. Windows has changed all of its internal locks to be unfair over time in order to combat this problem, and CLR monitors are also unfair.
The only real solution to the fundamental convoy problem is to reduce lock hold times and to factor your system so that there are very few (if any) hot locks. This is easier said than done, but is crucial for scalability.


A stampede is a situation where many threads are awakened, such that they all fight for attention simultaneously from the Windows thread scheduler. If you have 100 threads blocked on a single manual-reset event, for example, and you set that event … well, you're apt to have a real mess on your hands, particularly if a large portion of those threads will have to wait again.
One way to implement a blocking queue is to use a manual-­reset event that gets unsignaled when the queue is empty, and becomes signaled when it is non-empty. Unfortunately, when there are a large number of waiting threads during the transition from zero elements to one element, a stampede can occur. That's because only one thread will take the single element, which transitions the queue back to empty, and necessarily involves resetting the event. If you had 100 threads waiting, then 99 of them will wake up, context switch (and incur all those cache misses), just to realize they have to wait again.


Two-Step Dance
Sometimes you need to signal an event while holding a lock. This can be unfortunate if the waking thread needs to acquire the lock held, because it will be awakened only to find out that it must wait again. This is wasteful and increases the number of overall context switches. This situation is called the two-step dance, and can extend far beyond just two steps if many locks and events are involved.
Both Win32 and the CLR's condition variable support inherently suffers from the two-step dance problem. It is often unavoidable, or prohibitively difficult to work around.
The two-step dance issue is even worse on a single-processor machine. When events are involved, the kernel will apply a priority boost to the awakening thread. This is nearly guaranteed to preempt the thread setting the event before it has a chance to release the lock. This is two-step dance in the extreme, where the setting ThreadA is context switched out so that the awakening ThreadB can attempt to acquire the lock; it of course cannot, and so it will context switch out so that ThreadA can run again; eventually, ThreadA will release the lock, which again will priority boost ThreadB, which preempts ThreadA so that it can run. As you can see, there's a lot of wasteful context switching going on.


Priority Inversion
Modifying thread priorities is usually asking for trouble. Priority inversion can arise when many threads at different priorities share access to the same locks and resources, whereby a lower-priority thread actually indefinitely holds up the progress of a higher-priority thread. The moral of this story is to simply avoid changing thread priorities wherever possible.
Here is an extreme example of priority inversion. Imagine ThreadA at Low priority acquires some lock L. Then comes along ThreadB, which is at High priority. It tries to acquire L, but cannot because ThreadA holds it. This is the "inversion" part: it's as if ThreadA is artificially and temporarily given a higher priority than ThreadB, simply because it holds a lock that ThreadB needs.
The situation will eventually resolve itself when ThreadA releases the lock. Unfortunately, imagine what happens if ThreadC at Medium priority comes into the picture. Although ThreadC doesn't need lock L, its mere presence may prevent ThreadA from running at all, which indirectly prevents the High-priority ThreadB from running.
Eventually the Windows Balance Set Manager thread will notice this situation. Even if ThreadC remains runnable forever, ThreadA will eventually (after four seconds) receive a temporary priority boost by the OS. Hopefully this is enough to allow it to run to completion and release the lock. But the delay here (four seconds) is huge, and if there is any user interface involved, the application's user is certainly going to notice the problem.


Patterns for Achieving Safety
Now that I've chased down issue after issue, the good news is that there are design patterns you can follow to make the occurrence of many of the above issues (particularly the correctness hazards) far less frequent. The crux of most issues is that state is shared among multiple threads. What's worse, this state is freely manipulated, and it transitions from a consistent state to an inconsistent one and then (hopefully) back again with surprising regularity.
As developers write code for single-threaded programs, all of this makes sense. It's easy to use shared memory as a sort of scratch pad as you make your way towards a valid and final destination. C-style imperative programming languages have worked this way for quite a few years.
But with the rise of more and more concurrency, you need to pay closer attention to these habits. And you can take a cue from functional programming languages like Haskell, LISP, Scheme, ML, and even F# (a new .NET-compliant language), by adopting immutability, purity, and isolation as first class design concepts.


Immutability
An immutable data structure is one that doesn't change after construction. This is a wonderful property for concurrent programs because if data isn't being mutated, then there is no risk of conflict if many threads access it at once. That means synchronization isn't a concern.
Immutability has some support in C++ by way of const, and in C# by way of the read-only modifier. For example, a .NET type that has only read-only fields is shallow immutable. F# creates shallow immutable types by default, unless you use the mutable modifier. Going a step further, if each of those fields itself refers to another type whose fields are all read-only (and only refers to deeply immutable types), then the type is deeply immutable. This results in an entire object graph that is guaranteed to not change out from underneath you, which is very useful indeed.
All of this describes immutability as a static property. It's also possible for objects to be immutable by convention, meaning that there is some guarantee that state won't change during certain periods of time. This is a dynamic property. The Windows Presentation Foundation (WPF) freezable feature implements precisely this, and it also allows concurrent access without synchronization (although it cannot be checked in the same way that static support can). Dynamic immutability is often useful for objects that transition between immutable and mutable throughout the duration of their lifetime.
Immutability does have some downsides. Namely, whenever something has to change, you will need to make a copy of the original object and apply the changes along the way. Additionally, cycles in an object graph are generally not possible (except with dynamic immutability).
For instance, imagine you have an ImmutableStack, as shown in Figure 4. Instead of a set of mutating Push and Pop methods, you will need to return new ImmutableStack objects from them that contain the applied changes. Clever tricks can be used (as with the stack) in some cases to share memory among instances.
Figure 4 Using ImmutableStack
Copy Code
public class ImmutableStack {
private readonly T m_value;
private readonly ImmutableStack m_next;
private readonly bool m_empty;
public ImmutableStack() { m_empty = true; }
internal ImmutableStack(T value, Node next) {
m_value = value;
m_next = next;
m_empty = false;
}
public ImmutableStack Push(T value) {
return new ImmutableStack(value, this);
}
public ImmutableStack Pop(out T value) {
if (m_empty) throw new Exception("Empty.");
return m_next;
}
}

As nodes are pushed, you have to allocate a new object for each one. In a standard linked-list implementation of a stack, you'd have to do this anyway. Notice that as you pop elements from the stack, however, you can use the existing objects. That's because each node in the stack is immutable.
There are already immutable types running rampant in the wild. The CLR's System.String class is immutable, and there is a design guideline that all new value types should be immutable, too. The guidance being given here is to use immutability where is it possible and feels natural, and to resist the temptation to perform mutation simply because it is made convenient by the current generation of languages.


Purity
Even with immutable data types, most operations performed by a program are method calls. And method calls can have side-effects, which are problematic in concurrent code because a side-effect implies mutation of some form. Most often this will be a simple write to shared memory, but it can also be a physically mutating operation like a database transaction, Web service invocation, or file system operation. In many circumstances, I'd like to be able to invoke some method without fear that it will lead to concurrency hazards. Good examples of this are simple methods like GetHashCode and ToString on System.Object. Most people wouldn't expect them to entail side-effects.
A pure method can always be run in a concurrent setting without added synchronization. Although there is no common language support for purity, you can define a pure method very simply:
It only reads from shared memory, and it only reads immutable or constant state.
It can, of course, write to local variables.
It may only call other pure methods.
The set of things possible within a pure method, thus, is extremely limited. But when combined with immutable types, purity can be made possible and convenient. Some functional languages assume purity by default, most notably Haskell where everything is pure. Anything that must perform a side-effect has to be wrapped in a special thing called a monad. Most of us don't use Haskell, however, so we'll have to get by with purity-by-convention.


Isolation
Publication and privatization were mentioned in passing earlier, but they strike at the heart of a very important issue. Synchronization is necessary—and immutability and purity are interesting—because state is ordinarily shared among multiple threads. But if state is confined within a single thread, then there is no need for synchronization. This leads to more naturally scalable software.
Indeed, if state is isolated, mutation can happen freely. This is convenient because mutation is a fundamental built-in aspect of most C-style languages. Programmers are accustomed to it. It takes discipline to program in a mostly functional style, and is quite difficult for most developers. So give it a try, but don't deceive yourself into thinking the world will become functional overnight.
Ownership is a difficult thing to track down. When does an object become shared? When it is initialized, that is being done by a single thread and the object itself is not reachable from other threads just yet. Once a reference to that object is stored in a static variable, someplace that has been shared at thread creation or queuing time, or a field of an object transitively reachable from one of these places, the object becomes shared. It is imperative that developers watch specifically for these transitions between private and shared, and treat all shared state with care.


Joe Duffy is the Development Lead for Parallel Extensions to .NET at Microsoft. He spends most of his time hacking code, overseeing the design of the library, and managing an amazing team of developers. His new book is Concurrent Programming on Windows.

Monday, August 3, 2009

UNIX command

http://www.softpanorama.org/Tools/Find/finding_world_writable_abandoned_and_other_abnormal_files.shtml
clean out core dumps and temporary files
find . \( -name a.out -o -name '*.o' -o -name 'core' \) -exec rm {} \;




find . -type f -name "*.java" | xargs tar rvf myfile.tar

Monday, June 22, 2009

SVN setup

inst subversion
inst tortiose
create repository
change passwd file in repositiry
change the conf file in reposito to accept passwd file

now set the svn to become a service

sc create svnserve binpath= "\"C:\Program Files\Subversion\bin\svnserve.exe\" --service -r H:\backup\SVNRepo" displayname= "Subversion Server" depend= Tcpip start= auto

How to change color of JTable row having a particular value

http://www.java-forums.org/awt-swing/541-how-change-color-jtable-row-having-particular-value.html

-31-2007, 10:08 PM
johnt
Super Moderator Join Date: Apr 2007
Posts: 30


How to change color of JTable row having a particular value
I am trying to change the color of entire row which is having a column of value "FAIL". Here is my code, which is changing only that particular column. But i want to change the entire row.

Can anyone please give me an idea?

Code:
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int col)
{

String s = table.getModel().getValueAt(row,col).toString();

if(s.equalsIgnoreCase("Fail")) {
setForeground(Color.red);
}else {
setForeground(null);
}

return super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, col);

}

Sponsored Links


#2 (permalink) 05-31-2007, 10:12 PM
levent
Senior Member Join Date: Dec 2006
Posts: 748


If you know the column in the model that the test value will reside in, set it as a constant and your could would end up looking like this.

Code:
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int col)
{
Component comp = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, col);

String s = table.getModel().getValueAt(row, VALIDATION_COLUMN ).toString();

if(s.equalsIgnoreCase("Fail"))
{
comp.setForeground(Color.red);
}
else
{
comp.setForeground(null);
}

return( comp );
}

Tuesday, May 12, 2009

C# in VBA

1) [ProgId("FastVBA.WebDownload")]
[ComVisible(true)]
X Register for COM interoper


2) http://codebetter.com/blogs/peter.van.ooijen/archive/2005/08/02/130157.aspx

Sign in | Join | Help

Do you twitter? Follow us @CodeBetter
Peter's Gekko

* Home
* About
* Contact

Sponsors
ASP.NET Web Hosting – Click Here: 3 Months Free!
The Lounge
Telerik

Telerik OpenAccess - extensive LINQ support, forward & reverse mapping, stored procedures and more

Ads by The Lounge
Syndication

* RSS for Posts
* Atom
* RSS for Comments

Recent Posts

* Keeping a long running Silverlight application alive under forms authentication
* Every picture tells a story
* DDD and repositories. Without nHibernate but with lazy loading
* The return of CopySourceAsHtml
* Paging in a sql result set

Tags

* ASP.NET
* Chatter
* Coding
* Data
* Featured
* Hardware
* Mobile
* Out of control
* Tablet PC
* User groups and meetings

View more
News

*


Subscribe with Bloglines
I'm test-driven!

Links

* Gekko Software
* My publications
* Is this code available in VB ?
* This blog is out of control

Archives

* April 2009 (2)
* March 2009 (1)
* February 2009 (3)
* January 2009 (1)
* December 2008 (3)
* November 2008 (2)
* October 2008 (1)
* September 2008 (2)
* August 2008 (1)
* July 2008 (1)
* June 2008 (4)
* May 2008 (4)
* April 2008 (2)
* March 2008 (2)
* February 2008 (2)
* January 2008 (3)
* December 2007 (2)
* November 2007 (3)
* October 2007 (4)
* September 2007 (2)
* August 2007 (1)
* July 2007 (1)
* June 2007 (2)
* May 2007 (1)
* April 2007 (2)
* March 2007 (3)
* February 2007 (6)
* January 2007 (4)
* December 2006 (6)
* November 2006 (7)
* October 2006 (4)
* September 2006 (4)
* August 2006 (6)
* July 2006 (4)
* June 2006 (9)
* May 2006 (6)
* April 2006 (8)
* March 2006 (9)
* February 2006 (10)
* January 2006 (9)
* December 2005 (4)
* November 2005 (7)
* October 2005 (12)
* September 2005 (11)
* August 2005 (10)
* July 2005 (9)
* June 2005 (9)
* May 2005 (11)
* April 2005 (12)
* March 2005 (11)
* February 2005 (27)
* January 2005 (15)
* December 2004 (12)
* November 2004 (12)
* October 2004 (11)
* September 2004 (9)
* August 2004 (9)
* July 2004 (15)
* June 2004 (13)
* May 2004 (13)
* April 2004 (15)
* March 2004 (21)
* February 2004 (23)
* January 2004 (14)
* December 2003 (15)
* November 2003 (21)
* October 2003 (30)
* September 2003 (13)
* August 2003 (12)
* July 2003 (5)
* June 2003 (4)

Advertisement
Peter's Gekko » Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword

I am a C# guy. This is a matter of personal preference, I know how to code with VB.NET but just prefer curly brackets. So far the differences were not really worth the (sometimes quite) flaming discussion, after all we're all programming against the same framework. But recently I felt forced into using VB.NET for a part of a project. Let me explain what happened.

At first sight creating COM servers with .NET is a snap. When you set Register for COM interop to true in the project options all public types and their public members are published via COM and can be used in VBscript or from VBA code in an Office application. Use the ComVisible attribute to hide a public member from COM.
Imports System.Runtime.InteropServices
Public Class MyfirstComClass
Public Sub DoSomethingForYourCOMclient()
' Your code here
End Sub

Public Sub DoMore()
' More code
End Sub

_
Public Sub DotNetOnly()
' This code cannot be called from a COM client
End Sub
End Class


A COM class, its interface and any events it might raise are identified by a couple of GUID's. The moment you need a little more control over your class you apply these from code and identify an object as one raising events. In VB.NET this is all done in one attribute.
Imports System.IO

_
Public Class FileWatcher
Public Const ClassId = "44558DD7-87AD-433f-9B1B-C478233D6C69"
Public Const InterfaceId = "959A6835-4768-4cd5-89BE-7D408C2B86AA"
Public Const EventsId = "02E3954F-5DC1-4ad9-9167-354F0E82BCA3"

Private WithEvents watcher As FileSystemWatcher
Private Sub watcher_Created(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles watcher.Created
RaiseEvent OnNewFile(e.FullPath)
End Sub

Public Sub Watch(ByVal dirName As String, ByVal filter As String)
watcher = New FileSystemWatcher(dirName, filter)
watcher.EnableRaisingEvents = True
End Sub

Public Event OnNewFile(ByVal fullFileName As String)

End Class


This example FileWatcher class contains the guids to identify it. The ComClassAttribute applies them. The class wraps up a .NET FileSytemWatcher. The Watch method instantiates the object, sets a directory to watch, and enables raising events. When a new file matching the filter is created the COMserver's OnNewFile event will fire. You can use the server in Word like this:
Dim WithEvents mywatcher As WordUtilsVB.FileWatcher

Private Sub Document_Open()
Set mywatcher = New WordUtilsVB.FileWatcher
mywatcher.Watch "C:\USR", "*.doc"
End Sub

Private Sub mywatcher_OnNewFile(ByVal fullFileName As String)
Documents.Open (fullFileName)
End Sub


Opening the documents fires up the COM server which will start watching for new Word Documents in my C:|USR directory. When a new file is found Word will open it. (Note that the *.doc filter will also open Word temp file). This is a handy utility and took just a couple of VB.NET lines.

Being a C# guy I would like to refactor this to C# because I want to be able to make multiple call to the watch method which should result in multiple directories being watched. The way VB.NET handles event handlers is somewhat clumsy. In C# I could code like this.
public class FileWatcher
{
internal const string ClassId = "44558DD7-87AD-433f-9B1B-C478233D6C69";
internal const string InterfaceId = "959A6835-4768-4cd5-89BE-7D408C2B86AA";
internal const string EventsId = "02E3954F-5DC1-4ad9-9167-354F0E82BCA3";

private ArrayList watchers = new ArrayList();

public void Watch(string dirName, string filter)
{
FileSystemWatcher watcher = new FileSystemWatcher(dirName, filter);
watcher.Created += new FileSystemEventHandler(watcher_Created);
watchers.Add(watcher);
}

public NewFile OnNewFile;


private void watcher_Created(object sender, FileSystemEventArgs e)
{
OnNewFile(e.FullPath);
}
}

[ComVisible(false)]
public delegate void NewFile(string fileName);


To define the event I have to declare the NewFile delegate. This should not be exported to COM so the ComVisible attribute is applied. On every call to Watch a new FileSystemWatcher object is created and in C# I can attach an eventhandler on the fly, no need to declare a method which explicitly handles a specific event of a specific object. (Perhaps my VB knowledge falls short here, but I don't know how to do this elegantly in VB. The handles way does not work here) The ArrayList stores all watchers.

The hard part is registering this class in COM. The COMclassAttribute is part of the MicroSoft.VisualBasic namespace so it is by default not available in a C# project. The easy way would be to reference the Microsoft.VisualBasic.dll and use it nevertheless. Which works to get to VB specific functions like the financial ones (summary).
[Microsoft.VisualBasic.ComClassAttribute(FileWatcher.ClassId, FileWatcher.InterfaceId, FileWatcher.EventsId)]
public class FileWatcher
{
internal const string ClassId = "44558DD7-87AD-433f-9B1B-C478233D6C69";


This code will build and run. But will not do what you want it to do. By default all public members are published in COM, the moment you start applying attributes results vary. Applying this VB attribute will result in a COM class without any members. To satisfy the COM registration process in C# requires these steps

* Declare a public interface which describes the COMinterface of the class
* Declare the class as implementing this interface
* Declare a public interface which describes the events the class can sink (COM jargon for raising events)
* Decorate this interface with an InterfaceType attribute an IDispatch interface
* Decorate the class with a ComSourceInterface attribute
* Decorate the class with ClassInterface attribute
* Decorate the COMinterface, the eventsink interface and the class with Guid attributes

Resulting in :
namespace WordUtils
{
[Guid(FileWatcher.InterfaceId)]
public interface IfileWatcher
{
void Watch(string dirName, string filter);
}

[Guid(FileWatcher.EventsId)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IfileWatcherEvents
{
void OnNewFile(string fullFileName);
}

[Guid(FileWatcher.ClassId)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IfileWatcherEvents))]

public class FileWatcher : IfileWatcher
{
internal const string ClassId = "44558DD7-87AD-433f-9B1B-C478233D6C69";
internal const string InterfaceId = "959A6835-4768-4cd5-89BE-7D408C2B86AA";
internal const string EventsId = "02E3954F-5DC1-4ad9-9167-354F0E82BCA3";

private ArrayList watchers = new ArrayList();

public void Watch(string dirName, string filter)
{
FileSystemWatcher watcher = new FileSystemWatcher(dirName, filter);
watcher.Created += new FileSystemEventHandler(watcher_Created);
watchers.Add(watcher);
}

public NewFile OnNewFile;


private void watcher_Created(object sender, FileSystemEventArgs e)
{
OnNewFile(e.FullPath);
}
}

[ComVisible(false)]
public delegate void NewFile(string fileName);
}


This is a lot more code than the VB.NET version. On the other hand in this code you do have a better overview of what this class looks to COM. Just read the two interfaces
[Guid(FileWatcher.InterfaceId)]
public interface IfileWatcher
{
void Watch(string dirName, string filter);
}

[Guid(FileWatcher.EventsId)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IfileWatcherEvents
{
void OnNewFile(string fullFileName);
}


But there is a nasty problem with this code. When it comes to events it just does not work. The VBA designer in Word will "build" the code but as soon you run it it pops up a very nasty error:

This is described in the MS knowledge base here, but that does not really help as it makes clear there is no workaround. What is happening exactly is hidden inside the framework, the C# code seems to delegate the sinking of events to an object which VBA cannot work with. You can build C# COM servers which sink events properly. In the beta days of 1.0 I have been ploughing my way into .NET via COM. At the time unaware of the great (intended) COM event support I created a base class with working event support, implementing the desired interfaces (IConnectionPointContainer and its allies) all by hand. It's quite a long story, you can find it here and it does have sample code.

I'm "afraid" this is another notch for VB.NET, the second one when it comes to COM. I have to admit VB works very nice with named parameters and this is another one. But I'm going to be happy with the nice things of both languages. I'll use C# to solve the internal event handling stuff and I'll use VB.NET to make a COM wrapper. After all both languages live happy together in the .NET framework. To paraphrase Chuck Yeager: "it's the framework, not the language".

It takes just one keyword to get the C# COM server working as intended. Change

public NewFile OnNewFile;

to

public event NewFile OnNewFile;

and everything works. Read the background here.


Posted 08-02-2005 12:11 PM by pvanooijen
Filed under: Coding

[Advertisement]
Red-Gate
Comments
Sean wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-02-2005 10:44 AM
In VB.NET, you should be able to add your event handlers via code as in:

Dim watcher as FileSystemWatcher = New FileSystemWatcher(dirName, filter)
AddHandler watcher.Created AddressOf watcher_Created
watchers.Add(watcher)
pvanooijen wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-02-2005 12:01 PM
Thanks, that is the syntax I was looking for.

The most interesting thing is that after refactoring the VB class to the same pattern as the C# class results the VB class will show the same error.
Now the 459 error begins to make more sense. Delegating the handling of the event to another object, in the case the watcher object, will produce the problem. In both languages.

So instead of looking for the VB addhandler syntax I'll have to look for the C# equivalent of handles.

To be continued..

Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on 08-03-2005 4:37 PM
Äfter a crash course comes sinking in. This post is a rewrite of yesterdays one on events in VB.NET....
Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on 08-04-2005 4:23 AM
After a crash course comes sinking in. This post is a rewrite of yesterdays one
on events in VB.NET....
Peter's Gekko wrote Handles, AddHandler and RemoveHandler in VB.NET
on 08-05-2005 12:07 PM
After a crash course comes sinking in. This post is a rewrite of yesterdays one
on events in VB.NET....
Peter's Gekko wrote Handles versus Addhandler , a crash course in VB.NET event support (Error 459 revisited)
on 08-05-2005 12:10 PM
In my previous post
on the handling of COM events I described how I was driven into the
arms of VB.NET....
Visitor wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-10-2005 8:28 AM
To fix the nasty problem on using the C# COM server you have to declare the event with:

public event NewFile OnNewFile;
pvanooijen wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-10-2005 9:51 AM
That's great. Now Word does create the object without any errors. But as far as I can see the events don't hook in :? Look into that after my holiday.

A bit of a pitty you would need such a, at first sight superfluous keyword, to get it working. Not really in the spirit of C#.
Visitor wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-11-2005 2:19 AM
You can see the events, if you enable the watcher to raise some events with:

watcher.EnableRaisingEvents = true;

So it should do what you want.
savage wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-11-2005 10:01 AM
I'm trying to get this very thing working between Delphi and a C# application. I'm creating a COM class in C# and attempting to attach an event from within Delphi, but not having any luck. Any suggestions?
pvanooijen wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 08-30-2005 5:00 AM
The Events keyword indeed does the trick. I had indeed forgotten to set the filewatcher's enableraisingevents property. Setting it gave me my intended utility.

I'll write a wrapup post on the events keyword, it's documentation is bad and the idea is (looking back) quite simple.

I'll also write a post on eventsupport in Delphi, for the time you can find loads off material on this on my website www.gekko-software.nl
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on 08-31-2005 4:08 PM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on 08-31-2005 4:11 PM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Peter's Gekko wrote The C# event keyword is an access modifier for delegate members
on 09-01-2005 11:54 AM
Recently I had trouble getting COM events to work in a COM automation server written in C#. A visitor's...
Peter's Gekko wrote Is this code available in VB ?
on 10-06-2005 5:32 AM
This is a question I often get. I'm a C# guy but that is just a matter of personal preference. It's the...
Khash wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 12-16-2005 12:28 PM
I think I have found a bug in CCW
Have a look at this:
http://sajadi.co.uk/dflat/archives/2005/12/net_com_callabl.html
Rogelio wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 09-21-2006 10:16 AM

I created a COM class using the first sample you provided:

Imports System.Runtime.InteropServices

Public Class MyfirstComClass

Public Sub DoSomethingForYourCOMclient()

' Your code here

End Sub

Public Sub DoMore()

' More code

End Sub

_

Public Sub DotNetOnly()

' This code cannot be called from a COM client

End Sub

End Class

The problem I'm having is calling the DoMore() public sub from javascript. Is there a way to do this?
pvanooijen wrote re: Creating a COM server with .NET. C# versus VB.NET and the WithEvents keyword
on 09-21-2006 1:20 PM

To make the call from JavaScript you have to create the COM object in JavaScript. Creating a COM (ActiveX) object in the browser is not a path to follow except when you don't see any other solution.
Add a Comment
Name: (required) *
Website: (optional)
Comments (required) *
Remember Me?

Verify that you are a human,
drag scissors into the circle.

*
*
*
*
*

Ajax Fancy Captcha

About CodeBetter.Com

CodeBetter.Com FAQ
Our Mission
Advertisers should contact Brendan


Subscribe

Google Reader or Homepage
del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo


Member Projects

Sarasota Web Design - David Hayden
Patterns & Practices - David Hayden
dotMath - Steve Hebert
Structure Map - Jeremy D. Miller
StoryTeller - Jeremy D. Miller
The Code Wiki - Karl Seguin


Friends of CodeBetter.Com

Red-Gate Tools For SQL and .NET
Telerik
ComponentArt
VistaDB
JetBrains - ReSharper
Beyond Compare
.NET Memory Profiler
NDepend
AliCommerce
Ruby In Steel
SlickEdit
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
AForge.NET
Unfuddle
Balsamiq Mockups
Scrumy <-- NEW Friend!

3)How to create Excel UDFs in VSTO managed code

One question that I frequently get is how to call managed code from VBA. In general it is not recommended to mix VBA with managed code mainly due to the non-deterministic eventing model. In other words if VBA and managed code are listening for the same event there is no guarantee of the order that the handlers will be called. Another issue with using VBA and VSTO in the same solution is that you now have to deal with two separate security models. With that said, there are still times when you want to call VSTO code from VBA. One scenario is that you are upgrading an existing VBA solution to use VSTO. In this scenario you are keeping all of the existing VBA and are adding new capabilities to your solution using VSTO. Another scenario is that you want to create a solution in VSTO but you want to use User Defined Functions (UDF) in Excel. UDFs still require that they be written in VBA, but you can create your UDFs in managed code and call them from VBA. This is the technique that I describe below. This solution requires that you pass a reference to your managed code to VBA. Once the you have a reference to the managed code you can call that code from VBA. I recommend creating a wrapper in VBA for the managed functions this allows you to “call” the managed code from VBA.

Here is any easy way to call Managed functions from VBA.

*
1. Create a class with your functions in VSTO

_
Public Class MyManagedFunctions
Public Function GetNumber() As Integer
Return 42
End Function
End Class

2. Wire up your class to VBA in VSTO

Private Sub ThisWorkbook_Open() Handles Me.Open
Me.Application.Run("RegisterCallback", New MyManagedFunctions)
End Sub

3. Create Hook for managed code and a wrapper for the functions in VBA

In a VBA module in your spreadsheet or document
Dim managedObject As Object

Public Sub RegisterCallback(callback As Object)
Set managedObject = callback
End Sub

Public Function GetNumberFromVSTO() As Integer
GetNumberFromVSTO = managedObject.GetNumber()
End Function

Now you can enter =GetNumberFromVSTO() in a cell, when excel starts the cell value should be 42.


Published Friday, December 31, 2004 8:01 PM by pstubbs

Friday, April 24, 2009

IE C# 2

http://www.codeproject.com/KB/vb/kirangoka.aspx

Introduction

Microsoft Internet Explorer comes with a fairly comprehensive, although sparsely documented, Object Model. If you've used the Web Browser control in Access, you are already familiar with the capabilities of IE's Object Model. All of the functionality in IE's object model (not counting external support, like scripting support etc.) is provided by the following two dlls:

* shdocvw.dll (Microsoft Internet Controls)
* mshtml.tlb (Microsoft HTML Object Library)

You can automate IE to save a HTML file locally , inspect all the elements, and parse out a particular item at runtime.

Here's some sample code that automate through Internet Explorer windows login into the rediffmail.com, if the user name and password are valid.

First the application opens the http://rediff.com site. It types the user name and password at specified location and click the submit button so that it goes to inbox page. It also opens the compose page for the particular user.

The application extensively uses shdocvw.InternetExplorer object and mshtml.Document object.
Collapse

Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load

Collapse

Dim wbBrowser As New SHDocVw.InternetExplorer wbBrowser.Visible = True
wbBrowser.Navigate("http://www.rediff.com", Nothing, Nothing, Nothing, Nothing) Do
Loop Until Not wbBrowser.Busy
LoginIntoSite(wbBrowser)
OpennComposePage(wbBrowser)

Collapse

End Sub

Public Sub LoginIntoSite(ByRef wbBrowser As SHDocVw.InternetExplorer)

Dim HTMLDoc As mshtml.HTMLDocument

Do
Loop Until Not wbBrowser.Busy

HTMLDoc = wbBrowser.Document

Dim iHTMLCol As IHTMLElementCollection
Dim iHTMLEle As IHTMLElement
Dim str, userName, passwd As String


iHTMLCol = HTMLDoc.getElementsByTagName("input")



' Type the user name in the username text box
For Each iHTMLEle In iHTMLCol
If Not iHTMLEle.getAttribute("name") Is Nothing Then
str = iHTMLEle.getAttribute("name").ToString
If str = "login" Then
iHTMLEle.setAttribute("value", "")
Exit For
End If
End If
Next

' Type the password in the password text box
For Each iHTMLEle In iHTMLCol
If Not iHTMLEle.getAttribute("name") Is Nothing Then
str = iHTMLEle.getAttribute("name").ToString
If str = "passwd" Then
iHTMLEle.setAttribute("value", "")
Exit For
End If
End If
Next

' Press the submit button
For Each iHTMLEle In iHTMLCol
If Not iHTMLEle.getAttribute("name") Is Nothing Then
If iHTMLEle.outerHTML = " " height=21 width=26 " & _
"src=""http://im.rediff.com/" & _
"uim/rm_go_but.gif"" border=0>" Then
iHTMLEle.click()
Exit For
End If
End If
Next

Do
Loop Until Not wbBrowser.Busy





End Sub

Public Sub OpenComposePage(ByRef wbBrowser As SHDocVw.InternetExplorer)

Dim HTMLDoc1 As mshtml.HTMLDocument
Dim iHtmlCol As IHTMLElementCollection
Dim iHtmlEle As IHTMLElement

Do
Loop Until Not wbBrowser.Busy

HTMLDoc1 = mshtml.HTMLDocument



iHtmlCol = HTMLDoc1.getElementsByTagName("a")

' Press the anchor tag to open compose page
For Each iHtmlEle In iHtmlCol
If Not iHtmlEle.outerText Is Nothing Then
If iHtmlEle.outerText.ToLower = "write mail".ToLower Then
iHtmlEle.click()
Exit For
End If
End If
Next

Do
Loop Until Not wbBrowser.Busy
End Sub

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)