# blog

 博客园 首页 新随笔 联系 订阅 管理

## Introduction

Nothing unusual... this article is a compilation of questions and answers which were asked between 10 December 2004 and 23 Jan 2005 (45 days) on the Code Project Visual C++ forum. Also, this is the first article of the 45 Days series. I hope, I will bring more on this series.

Thanks to people for their contributions on the CodeProject forum to help fellow peers in their need. I have changed some original comments to suit/maintain the look/feel of article (I beg apology for that). If I have missed something, please feel free to mail me or leave a comment at bottom.

## Content

### [10 Dec to 18 Dec 2004]

#### Q 1.01 Is there any function to minimize the window?[top^]

A. ThatsAlok quoted :-

If you are using MFC: this->ShowWindow(SW_MINIMIZE);

If you are using Win32 API based application: ShowWindow(hWnd,SW_MINIMIZE);

#### Q 1.02 How do I stop appearing of the SQL Sever login dialog again and again?[top^]

A. renjith_sree quoted :-

Use CDatabase::noOdbcDialog as the second parameter in OpenEx() method. E.g.:

extern CDatabase oDb;
extern CString csConnection;
oDb.OpenEx(csConnection, CDatabase::noOdbcDialog );

This will suppress the login dialog.

#### Q 1.03 How can I access USB port (COM 5)?[top^]

A. Antti Keskinen quoted :-

The USB is a bus that resides in the computer. The low-level drivers (supplied by Microsoft) allow the bus to enumerate and identify a piece of hardware and then send a request to the registry to find the correct function driver for the device by using the vendor and product IDs returned by the USB descriptors. This is how the bus works in a nutshell.

Your computer systems might have a pseudo-device driver that emulates a COM port. When this driver is loaded, it opens a handle to the low-level bus drivers and then creates a virtual COM port device. After this, passing a USB packet into the COM port is routed directly to the low-level drivers and thus into the bus. Needless to say, an erroneous packet might cause misbehavior on the system. This is probably what your boss had in mind. You should ask him for clarification, though.

When this pseudo-device driver is not in use, all devices attached to the bus are represented by device objects. For each hardware device object that has a suitable function driver available and loaded, a driver object also exists. Additionally, possible filter driver objects may exist. You can use the WinObj object viewer (Google for it) to view all hardware device objects, driver objects and other objects currently existing in your system. The same program can be used to obtain a valid name for a driver/device object. If you are operating on kernel mode, you can use this low-level name to open a handle into the driver/device. In user mode, only the symbolic link names and a restricted list of device names are available due to security restrictions imposed by Windows NT/2000/XP framework.

You can view all these through WinObj. The symbolic names can be found in the 'GLOBAL??' subtree. Actual device names can be found from the 'Device' subtree. For reference, try looking for a normal COM port. You can find it lying around there somewhere. "\Device\Serial0" is COM1 for me.

From this list (Global??), you can even identify your USB device by looking at the vendor and product IDs. To get a rough idea whose device you're looking at, you can use the Linux-USB group's list, which is "somewhat" regularly updated. It can be found here[^].All USB devices are listed in the form "USB#Vid_xxxx&Pid_xxxx&MI_xx#.....". The first is the vendor ID, the next the product ID. The last one I'm not sure of.

Remember that a device might have multiple entries in WinObj's "GLOBAL??" subtree. The one we are interested in is \Device\USBPDO-X which refers to a physical device object in the USB bus. Opening a handle to this device allows you to read/write from as if reading/writing a file. Security restrictions might apply, though. You can view these through WinObj as well. If you can't view the properties of an object, you don't have enough privileges. Looking at the Security tab, you can see which users have rights to read/write/modify a device.

For an example, Logitech has a vendor ID of 046d hex. I have the Logitech MX500 optical mouse attached, and its product ID is c025 hex. Both of these are from Linux-USB list. Thus, in "GLOBAL??", I have an entry "USB#Vid_046d&Pid_c025 etc" which is a symbolink link to "\DEVICE\USBPDO-5". This is the physical device object for my MX500. Opening its properties, I can see that in user mode, I only have 'query state' privilege, allowing me to request status information about the device. If I was logged in as an administrator, I could also 'delete' the object, which means the device was logically detached from the bus. The bus would, however, soon re-detect the device, re-load the drivers and re-create the device objects.

I can't, in user mode, read or write from the device. For that purpose, I would need to write a kernel-mode program. This program should create a virtual device, say USB MX500 mouse, open the device handle for USBPDO-5, and route the commands sent to the virtual device to the physical device and back. A crude hack, I'd call it, but it would fill its purpose.

#### Q 1.04 What window message is processed when A window is maximized or minimized?[top^]

A. prcarp quoted :-

Look at WM_SIZE:

wParam = SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED, etc.
lParam = cx -> lo word cy -> hi word

#### Q 1.05 What is the most suitable solution for running a timer every 40 msec?[top^]

A. John M. Drescher quoted :-

The problem is that the time slice is much larger than 1 ms. See this article: Time is the Simplest Thing...

Antti Keskinen quoted :-

Windows is not the best platform for time-critical applications. If you must use it, though, you could try increasing the priority of your application to maximum level. This ensures that the 40 ms (I assume milliseconds, here) timer is fired as close to 40 ms intervals as possible.

Increasing the priority of your application will cause other applications to lose theirs: increasing the accuracy of your application might/will cause inaccuracy/stiff response/high latency in other applications concurrently executing in the system. Pushing one application to real-time priority will most likely cause the operating system to appear 'locked up' while this single application is executing. The timer will reach as close to 40 ms intervals as possible, though. That's the price you'll have to pay.

When designing the real-time thread, you must make it as low-resource hog as possible.

For an example, create a thread, increase its priority and call SetTimer Win32 API routine with a pointer to the function that should run at 40 ms intervals. Then put this thread into a forever loop that can be interrupted, if necessary. When interrupted, the timer should be killed and the thread terminated. Note that this will not cause the system to lock up, because the priority of the process itself has not been raised. You could use SetPriorityClass to pump up the process priority as well. Before doing this, familiarize yourself with Scheduling Priorities[^] in the MSDN or in Visual Studio documentation. Misusing thread or process priorities is a sure way to get your computer locked up easily.

To set max priority for your MFC application's main thread, use AfxGetApp() to get the CWinApp object pointer, and call CWinThread::SetThreadPriority() with a parameter THREAD_PRIORITY_TIME_CRITICAL through this pointer. CWinApp derives from CWinThread. MFC does not have a direct routine to pump up process priority. You'd need to use a mixed-mode call (CWinThread::operator HANDLE and SetPriorityClass) to accomplish this.

A precisely 40 ms timer with not a single micro-second delay or advance is impossible in a modern operating system. For such a purpose, you'd need to design and implement a micro-controller or similar solution.

Named events are used to schedule inter-process actions, or inter-thread actions. For example, you could create an event object in a remote thread to mark when this thread has ran a single loop. When the event object is signaled, a loop is complete and the next loop is starting, if it's a continuous system. Event objects can be global or local, determining how they are created. Global for inter-process, local for inter-thread should be your general rule.

Even if you use named events, you would need some method to set the event to a signaled state whenever 40 ms has passed. This will again lead you back to the timing issue and the timers. Named events is the easiest way to signal other threads or processes that your 40 ms interval has passed, though.

#### Q 1.06 What is the syntax of WM_GETTEXT for retrieving text from an edit box?[top^]

A. Ravi Bhavnani quoted :-

Many (actually most) Windows API calls that operate on windows work by sending the target window a message. WM_GETTEXT is the message sent to retrieve a window's text. Both these code fragments will get the edit control's text:

 char szText [TEXTLEN];   HWND hWndEdit = window handle of edit control;
::GetWindowText (hWndEdit, szText, TEXTLEN - 1);
char szText [TEXTLEN];  HWND hWndEdit = window handle of edit control;
::SendMessage (hWndEdit, WM_GETTEXT,(WPARAM) TEXTLEN - 1,(LPARAM) szText);

#### Q 1.07 How to create a dialog which is not the main window, but its parent window and owner window are all NULL, such as the conversation window in MSN Messenger?[top^]

A. Mr.Prakash quoted :-

Make the parent window of each dialog as desktop window by calling GetDeskTopWindow().

#### Q 1.08 How to capture WEBCAM using Visual C++ or API?[top^]

A. Cyberizen quoted :-

There is an SDK available from Microsoft Research called "Vision SDK". With this SDK, you can connect to your webcam and capture images in a variety of formats. I have worked on a project using this SDK in my third year project in BS. Tell me if you want any additional help.

P.S.: Oh and I just learned that Microsoft has sold its Vision SDK product to some German company which might make it commercial so it might not be publicly available. Fortunately, I found a website for you that allows you to download the Microsoft version.

Antti Keskinen quoted :-

The most effective way to use an installed webcam is to use DirectShow, which comes with DirectX 9.

The webcam driver, when it is installed and loaded, creates a DirectShow filter for the video stream and pictures available from the camera. This filter offers one or more interfaces, depending on what services the camera has. If you build and operate a 'capture chain' (DirectShow term), you can capture live data from the camera into a Windows window, a file or a network stream.

To use DirectShow in your programs, you must download and install the latest DirectX SDK available freely from Microsoft. The DirectX documentation accompanying this SDK has a few examples and code samples on how to create capture chains. The process of creating a chain is similar every time: the filters that join the chain determine the nature, purpose and features of the chain.

For example, to use a webcam to get live data from the camera to a Windows window, create a capture chain with the webcam filter and a Video Rendering Mixer filter. VRM filter can render video data into a window you create and specify with a HWND parameter. Remember that the VRM filter creates an auxiliary window which is a child of the HWND you specify. The auxiliary window has no title bar, system menu or anything else. It's just a blank square which is constantly redrawn with video data. Thus you need an actual top-level window which allows you to control the video display. You can't create a program and just put a video window over the desktop, as you would then have no way of closing the program without CTRL+ALT+DEL.

#### Q 1.09 What does the ^ do in C++?[top^]

A. toxcct quoted :-

^ is the bitwise exclusive-or operator
SO : 0x1100 ^ 0x1010----------- = 0x0110
that's why number ^= 1; means number = number ^ 1;
means number = 0 ^ 1; // == 1

PJ Arends quoted :-

See this: An introduction to bitwise operators.

#### Q 1.10 How do I do exponents in C++? If ^ is XOR...[top^]

A. Ryan Binns quoted :-

Use the pow() function.

#### Q 1.11 How do we run an EXE file at Windows startup?[top^]

A. goodmast3r quoted :-

Just make a shortcut in the Start>Programs>Startup

Arsalan Malik quoted :-

Add path (string value) of your EXE to following location in the registry: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run.

vishalmore quoted :-

Add path of your EXE to following location in the registry: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run.

#### Q 1.12 What's the difference between keyword and reserved word?[top^]

A. Sujan Christo quoted :-

#### Q 1.13 How can I prevent a dialog from resize and move?[top^]

A. Blake Miller quoted :-

The WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.

If you set both sizes the same, I am pretty sure your window's size will not adjust. You just make its minimum and maximum size the same. I have not tested this exact behavior, however, it is just the first idea that came to my mind.

#### Q 1.14 How to write a .ini file of an application?[top^]

A. Greeeg quoted :-

The GetPrivateProfileXXX and WritePrivateProfileXXX functions do the job for you.

#### Q 1.15 How to set the TAB order of a control at runtime manually?[top^]

A. Ryan Binns quoted :-

The tab order is simply the Z-order of the windows, so to change it use SetWindowPos()

#### Q 1.16 What's the functionality of DEBUG_NEW ?[top^]

A. PJ Arends quoted :-

It implements the ability of the debugger to be able to track the line number and file name of where any memory leaks were allocated.

#### Q 1.17 What are the differences between a DLL and a LIB file?[top^]

A. John R. Shaw quoted :-

In the past, if you linked in a normal .LIB file, then you had linked in every function that was contained in that file, whether you used them are not. I do not know if that is still the case, but it resulted in programs that where much larger than required to do the job, since most of the functions linked in where not used. Plus the fact that every program had there own versions of the same function code.

If the same functions from the same library are used in several programs, then you should use a DLL. That way all the programs can share the same code: this reduce the size of the individual programs and reduces the amount of disk space required to store the programs and libraries they depend on. It also reduces the amount of memory required to load your program.

#### Q 1.18 Give me some method for determining the full path to my application?[top^]

A. Antony M Kancidrowski quoted :-

Here is a function that will do the job for you. Yea, I know it is global but you can take the contents and wrap them in a class function if you like!

 inline CString GetModuleLoadPath()
// Returns the load path of the module (ends in '\')
{
int Idx;
TCHAR ModName[_MAX_PATH];

if(!::GetModuleFileName(NULL,ModName,sizeof(ModName)) )
{
ASSERT(false);
return CString(_T(""));
}

if( Idx == -1 )
{
ASSERT(false);
return CString(_T(""));
}

}

#### Q 1.19 What are Guard bytes ?[top^]

A. peterchen quoted :-

malloc_dbg calls malloc, but requests a few more bytes. These bytes are filled with a predefined value. free_dbg then checks if these extra bytes still hold this value. If they did, you probably wrote beyond the allocated memory (the VC Runtime prints a diagnostic message to the debug output). Typical implementations add 4 bytes at the end.

In this case, using free instead of _free_dbg is often not a problem, but depending on the implementation, it might leak the guard bytes. But if an implementation adds guard bytes *before* the memory provided to you (to detect underflows, which are less common), using free instead of -free_dbg is likely to corrupt the heap.

#### Q 1.20 How to debug a running DLL?[top^]

A. avenger_sb25 quoted :-

Well, if you are using the Visual Studio IDE, press F9 to set a breakpoint in the source file. Then, go to: Project>>Settings>>Debug tab. In the "Executable for debug session:" edit box, browse and select the EXE file that is going to use your DLL. Then press 'OK'

Now run your program by clicking the '!' icon or on the toolbar. This will run the EXE that you selected earlier. Now if that program (EXE) makes use of an exported function from your DLL, and if you have setup your breakpoints correctly, you can debug your DLL......

renjith_sree quoted :-

Put the EXE file name in Project>Settings>Debug (executable for debug section).

### [19 Dec to 27 Dec 2004]

#### Q 2.01 How to connect Modem to telephone ?[top^]

A. Antti Keskinen quoted :-

You should use TAPI (Telephony API) instead of Win32 CreateFile. See Visual Studio docs or MSDN for a reference and examples. TAPI is installed with Platform SDK, so it comes bundled with most Visual Studio distributions, and/or you can download it from the Internet as well.

TAPI has a function pair called lineGenerateDigits and lineGatherDigits that generate and gather pulse sequences that represent numbers. You can also send and monitor individual pulses with lineGenerateTone and lineMonitorTone.

These functions only exist in TAPI version 2.x. In version 3.x, the COM model is introduced, and everything running on the phone line is considered a stream, with terminal objects acting as sinks. For your case, I suggest TAPI 2.x, if possible. The COM model is too complex for the functionality you require.

#### Q 2.02 How to identify a user who is having specific kinds of privileges? (i.e. admin privilege, etc.) [top^]

A.DavidCrow quoted :-

Does NetUserGetInfo() do what you require?

#### Q 2.03 How to invoke a web service from a C++ project with a structure as parameter? top[^]

A.Antti Keskinen quoted :-

Are you using Visual Studio 6.0? If yes, consider moving to Visual Studio .NET 2003. It has the excellent Add Web Reference wizard, which will generate wrapper classes for Web Services. This means that if a Web Service's WSDL defines that it takes an array, the invoking method of the class also requires an array. If you can't upgrade the environment, try fetching the latest SOAP Toolkit from Microsoft and installing it. Its support will be retired in April 2005, but it's still available for download.

The main reason for SOAP Toolkit deprecation is the coming of .NET Framework, which inherently supports Web Services. Using .NET requires Visual Studio .NET 2002 or later, though, so you're in the same problem again. The SOAP Toolkit specifies the COM object SoapClient30. This COM object can initialize itself based on a WSDL file. Having said that, obtain a WSDL file for the Web Service you wish to use, use COM to create the SoapClient30 object, initialize it with the WSDL file, and you can directly call the method that takes an array as a parameter.

#### Q 2.04 How I can count the total number of characters typed in a RichEdit control?[top^]

A. DavidCrow quoted :-

How about GetWindowTextLength()?

#### Q 2.05 How to prevent an MFC dialog based app being displayed on the taskbar?[top^]

A. Mohammad A Gdeisat quoted :-

I quote the following from MSDN 2003, I don't know if it really works but I hope so: I will simply tell you the answer: you must create your dialog as a child of an invisible window that has WS_EX_TOOLWINDOW set, and you must make sure your dialog has the WS_EX_APPWINDOW style turned off. If you read the documentation’s fine print, you might figure this out—but only if you use a powerful magnifying glass.

// pre-create window: set WS_EX_TOOLWINDOW style
//
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if (CFrameWnd::PreCreateWindow(cs))
{
cs.dwExStyle |= WS_EX_TOOLWINDOW;
return TRUE;
}
return FALSE;
}

// InitInstance: create dialog as child of invisible main frame
//

BOOL CMyApp::InitInstance()
{
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;

CMyDlg dlg(pFrame);
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{ }
return FALSE;
}

#### Q 2.06 How to set display resolution in Windows?[top^]

A. DavidCrow quoted :-

What about ChangeDisplaySettings()?

#### Q 2.07 How do I send a specific key to a window?[top^]

A. Antti Keskinen quoted :-

The WM_KEYDOWN message is sent to a window when the window has focus and a non-system keyboard key goes down and remains pressed. After the keyboard repeat delay, multiple WM_KEYDOWN messages are simultaneously generated. A non-system keyboard key is any key excluding F10 and keys pressed together with ALT. To simulate an ALT + key combination, use WM_SYSKEYDOWN message.

In order to simulate a key press to a window, use WM_CHAR message. WM_CHAR messages are not translated anymore, so the key code you issue for it will proceed directly as-is to the receiving window. WM_KEYDOWN messages have virtual key-codes that are translated to character codes. WM_CHAR messages have character-code (ASCII) values with them.

To precisely simulate a key press (such as CTRL/SHIFT + key), you must generate virtual key press events. This is much more complicated than just sending a single message. Check SendInput in MSDN. In here, you will generate sequential keyboard events for each and every event of the key combination. Remember that pressing CTRL + SHIFT + F, for example, consists of first setting CTRL, SHIFT and F keys to pressed state, in order, and then releasing them, in inverse order. Note that to target the key press combination, you must set the target window active by using SetFocus.

Also, if your program is running on a separate thread than the target program, you must first attach the input streams by using AttachThreadInput, and detach them after you've synthesized the keystrokes.

#### Q 2.08 I need to check somehow when a process starts or exits. Any ideas how we can do this?[top^]

A. ThatsAlok quoted :-

You have to set a system wide Hook on the process of type WH_CBT and listen for WM_QUIT, WM_CREATE messages. SetWindowHookEx will be the API use in this case!

#### Q 2.09 How to convert between dialog units to pixels and vice versa?[top^]

A. DavidCrow quoted :-

This is a very bad idea. Dialog units are used for a reason, namely so that a program does not have to be concerned with what resolution and font are currently in use. By hard-coding controls based on pixel size, you have limited the portability of your program to only one computer. See this comment for more.

Michael Dunn quoted :-

Use MapDialogRect() to do that conversion.

#### Q 2.10 How do I check what version of the compiler I am using?[top^]

A. Michael Dunn quoted :-

Test the _MSC_VER symbol. For VC 7, it's 1300; for VC 7.1, it's 1310; and for VC 6 with compiler version 12.00, _MSC_VER is 1200.

#### Q 2.11 How to output messages/text to screen at XP boot time from a Win32 console application?[top^]

A. Michael Dunn quoted :-

Here's a start: HKLM\SYSTEM\CurrentControlSet\Control\Session Manager, string value BootExecute holds the command line to run.

WoutL quoted :-

e-sushi quoted :-

Guess I found some more useable stuff... Windows Driver Build Methods and Tools.

#### Q 2.12 How to use SetTimer( ) when in a MFC regular DLL?[top^]

A. Ravi Bhavnani quoted :-

SetTimer() is a method of the CWnd class. Your usage of the function invokes the globally scoped ::SetTimer() Windows API call which takes a window handle as the first argument. Passing a value of "1000" will likely cause abnormal behavior.

You should pass your DLLClass object a valid CWnd (or window handle) which can be passed to the SetTimer() call within Test().

#### Q 2.13 Does anyone know how to upload files to a web server through HTTP by VC++?[top^]

A. Neville Franks quoted :-

Have a look at: InternetWriteFile().

I assume you'll need permission / authentication to do this. It is probably better to use FTP.

#### Q 2.14 How Can I draw inside an Edit control?[top^]

A. DELIVER THE PROMISE quoted :-

• You can derive a class from CEdit and handle OnPaint(). You will have a DC there. You can use it to draw like: dc.MoveTo() - dc.LineTo().
• Or you can call: CDC* pDC = CEdit.GetDC(); pDC->MoveTo(), pDC->LineTo().

### [28 Dec 2004 to 5 Jan 2005]

#### Q 3.01 How to get network IP address of computers?[top^]

A. DavidCrow quoted :-

To get the IP address of a machine, use gethostbyname().

#### Q 3.02 How to eliminate flickering when resizing a window?[top^]

A. SteveKing quoted :-

Try modifying CWnd::OnEraseBkgnd(..) which erases the background.

#### Q 3.03 How to find which window belongs to which EXE file?[top^]

A. Gary R. Wheeler quoted :-

Why not use the correct function: GetWindowModuleFileName().

#### Q 3.04 Is there any in-built function call to read the amount of memory or disk free space?[top^]

A. Michael Dunn quoted :-

C++ has no such functions built-in because that kind of info is inherently platform-specific. Check out the GlobalMemoryStatus() and GetDiskFreeSpaceEx() APIs.

#### Q 3.05 How to print/preview multiple pages?[top^]

A. PJ Arends quoted :-

#### Q 3.06 Any suggestion about burning CD "on the fly" ?[top^]

A. Henry miller quoted :-

First, if you have a choice, use DVD+R or DVD+RW for this, because they have the best support for preventing "under run". In fact if you are using CDs, to be legal you must be sure that your data stream is always big enough to write data when the drive is ready (even if you are not!)! I break this rule all the time on a modern drive, without too many problems, but if you sell this, you need to require that your customers have a drive with good underun protection.

Next, go to www.t10.org and buy the MMC standards (you can download them too, but not the latest versions...). You might want to consider joining, depending on how technical your people are. t10 is the SCSI standards organization. Every CD writer that is faster than 4x is SCSI! (It may be electrically IDE or USB, but it speaks the SCSI standard, so that is what you care about.) Read the standard several times until you think you understand it.

Now, figure out how to send SCSI commands on your OS. On Windows NT/2000/XP, it is a device_ioctl SCSI_PASSTHROUGH_DIRECT (or something like that). Windows 95/98/ME uses something else. UNIX is something different again, different for each UNIX.

Next you need to figure out what standard you will write data in. I don't know anything about the video CD standard, so I can't help you there. You can define your own format if you don't care about nothing else being able to read the disk.

If you want to write a file, then you can either figure out UDF (I didn't, but this is perhaps the right way to go), or you can write ISO-9660. ISO-9660 is most easily found under the name ECMA-119. Get the spec, and learn that inside and out. There is just one detail you need to know: reserve a track at the beginning of the disk, then write data to the next track, when done you write your directory to the reserved track.

It took me about 4 months to write this myself (design through release). I had the advantage of a SCSI abstraction layer in place so I didn't need to worry about many of the details you will need to learn. Once you understand the standards and have a design, the code is only a couple weeks, but it takes a while to figure out how to read all the standards.

#### Q 3.07 Can somebody give me a list of the Virtual Key codes?[top^]

A. Heath Stewart quoted :-

Constants like these are defined in the headers that are installed with VC++. If you find, for example, VK_UP then you can see all the others. They are defined in winuser.h and documented at MSDN.

#### Q 3.08 When do we use extern "C"? Is this a compiler-specific feature?[top^]

A. Lim Bio Liong quoted :-

The extern "C" declaration is used to tell the C++ compiler not to mangle the symbol which is being declared.

When the C++ compiler encounters a function name like "DisplayCurrentThreadId()" which has not been declared as extern "C", it will emit a symbol for it which will look like the following :

?DisplayCurrentThreadId@@YAXXZ

The actual symbol produced depends on the compiler used (the above was produced by VC++ 6.0). This symbol will be used in the resulting OBJ file for linking purposes.

C++ has a variety of reasons for symbol name mangling, of course. But the reason for the mangling of function names (both class functions and global ones) is to enable function name overloading (i.e. using the same function name with different parameter types).

If extern "C" was used to declare the function, the symbol produced for it could be:

_DisplayCurrentThreadId

This depends on the compiler used. But the bottom line is that no function name overloading will be allowed (since the C language does not support this, hence extern "C").

#### Q 3.09 How to write a web link to the Favorites folder ?[top^]

A. Michael Dunn quoted :-

See MSDN.

#### Q 3.10 Can anybody give me a code sample for getting the MS Outlook address book?[top^]

A. Ravi Bhavnani quoted :-

Perhaps this[^] article will help?

#### Q 3.11 How to set window size of an MFC Dialog at runtime ?[top^]

A. Ravi Bhavnani quoted :-

See SetWindowPos() and MoveWindow().

#### Q 3.12 How do I make a combo box non-editable ?[top^]

A. cedric moonen quoted :-

Go into the properties of your combobox -> 'Style' tab and select 'DropList' in the 'Type' combo.

#### Q 3.13 How do I create a DSN programmatically? [top^]

A. DavidCrow quoted :-

Use SQLConfigDataSource().

#### Q 3.14 How to show and hide the title bar of a modal dialog dynamically? [top^]

A. k_dehairy quoted :-

Try using this member function of the dialog:

//this will hide the title
ModifyStyle(WS_CAPTION,0);
//then call SetWindowPos()with cx and cy of your own
::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);

To get the toolbar back:

//this will show the title
ModifyStyle(0,WS_CAPTION);
::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);

#### Q 3.15 Could you provide me some resources (example: source code) to make global hotkeys in MFC?[top^]

A. ThatsAlok quoted :-

#### Q 3.16 How to add an icon to the system tray?[top^]

A. Michael P Butler quoted :-

ThatsAlok quoted :-

#### Q 3.17 How to use a C based Library in a C++ environment?[top^]

A. Michael Dunn quoted :-

In your C++ code, do this:

extern "C"
{
}

#### Q 3.18 Which file is modified if I modify the project settings by pressing Alt+F7?[top^]

A. ThatsAlok quoted :-

When you press Alt+F7, your Project.DSP will get modified.

#### Q 3.19 How to check if a file has been opened by any process or not?[top^]

A. Rajesh match quoted :-

Look for CFile::shareExclusive in MSDN.

cmk quoted :-

#### Q 3.20 My Compiler points to WM_MOUSEWHEEL as "undeclared identifier", what is the problem?[top^]

A. PJ Arends quoted :-

From WinUser.h:

    #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define WM_MOUSEWHEEL 0x020A
#endif

Notice the #if? Make sure _WIN32_WINNT or _WIN32_WINDOWS is defined properly.

### [6 Jan to 14 Jan 2005]

#### Q 4.01 How to set the font of CListCtrl header?[top^]

A. basementman quoted :-

  //CFont Varible
CFont m_fArial;
//Create Arial Font
m_fArial.CreateFont(14,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,
DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Arial");
//Get Pointer of ListCtrl
CListCtrl *m_pList = (CListCtrl*)GetDlgItem(IDC_LIST1);
//Set Font if (m_pList)
m_pList->GetHeaderCtrl()->SetFont(&m_fArial);

The key here is to get a pointer to CListCtrl's embedded Header control.

#### Q 4.02 Will somebody refer me to source code for ZMODEM?[top^]

A. Ravi Bhavnani quoted :-

You could try porting this Unix example[^]. There's also some source here[^]. Also see this commercial source[^].

#### Q 4.03 How to use Crystal Reports in Visual C++?[top^]

A. Michael P Butler quoted :-

Have a look at this list of examples[^].

#### Q 4.04 Is there any s/w, utility to produce Audio Effect ?[top^]

A. Marcus Spitzmiller quoted :-

Last time I checked, DirectX does all of this in its DirectSound component: you can research or download the SDK here.

Ravi Bhavnani quoted :-

I use Bass[^].

#### Q 4.05 How to detect what URL was clicked by the user ?[top^]

A. Michael Dunn quoted :-

The OnBeforeNavigate2 event passes you the URL about to be navigated to.

Antti Keskinen quoted :-

Instead of IWebBrowser2, use standard COM methods and register for notifications from the DWebBrowserEvents interface. First query for IConnectionPointContainer interface. Then ask for IConnectionPoint interface for DWebBrowserEvents. Then register your class using IConnectionPoint::Advise.

The class you use must be derived from DWebBrowserEvents and must implement all of its methods. Unused events should return S_OK. The event you're interested in is DWebBrowserEvents::NavigateComplete. This event will have the final URL where the client was directed to.

#### Q 4.06 Why threads are declared as static when used from a class?[top^]

A. Toby Opferman quoted :-

Functions used to be created as threads are defined as "static" when used with a C++ class because there is an implied parameter that doesn't show up in code, the THIS pointer.

To avoid this confusion and make it simple, "static" class members only operate on static data and not per-instance data and as such the "this" pointer is not passed in. So, it's easy to define the function as static and use it in CreateThread without worries. Of course, they usually pass the object instance as the first parameter anyway.

class x {
public:
{
x *pX = (x *)lParam;
// Happy Happy Joy Joy
}
}................

x pX = new x;
CreateThread(...., x::MyThread, pX);

As you see in the above example, the thread can be created and the system will pass in the "this" pointer and we will manually re-use it.

Another way to do this in C++ is to simply define a class function to be standard call, not fast call, and take "void" parameters.

class x
{
public:
};
...
x *pX = new x;
CreateThread(..., x::MyThread, pX);

Why void parameters?

Because the system will now pass in the "this" pointer for you and in C++, the language hides this detail anyway.

Why stdcall and not fastcall?

STDCALL should pass the "this" pointer on the stack while fastcall passes the this pointer in the ECX register, which the system has no idea about.

#### Q 4.07 Where does Windows store log regarding dial-up connections?[top^]

A. Michael Dunn quoted :-

Look in your System event log, you'll see entries from the RemoteAccess service when a connection is made or disconnected.

#### Q 4.08 How to change the language in UI (User Interface) dynamically?[top^]

A. Maximilien quoted :-

The best to do, is to use multiple resource files, one for each language you use. Each resource will be in a DLL and will be loaded when the application starts (or after a user selects a menu item).

Have a look at:

#### Q 4.09 Any suggestion about Atomic clock and Time Zone Programming?[top^]

A. Mike Dimmick quoted :-

Modern versions of Windows (XP, 2003) come preconfigured to contact time.windows.com using the Simple Network Time Protocol[^]. If you join a machine to a 2000 or 2003 Active Directory domain, the machine then gets its time from the domain controller.

Second, I also need to display the time of other time zones, say I'm in LA, and want to display the time for London and NY. Does any body have links to information on how one would go about determining the time in other time zones, area?

My World Clock[^] sample application does this. Source code is available at that link - it's a C# application but uses OS function calls for the actual time conversions. The tricky bit is handling daylight savings time - otherwise it would be a simple offset calculation.

My biggest issue is with how the user can pick his location and how the software knows the timezone/etc. at that location?

You'd have to have some kind of database of locations and the corresponding time zones.

#### Q 4.10 How to read data from a sound card online?[top^]

A. K(arl) quoted :-

You could record this data using the Waveform-Audio interface. You may find information on how to use this API to record audio data at MSDN.

#### Q 4.11 What does IN/OUT mean when declaring variables?[top^]

A. DavidCrow quoted :-

Basically, it indicates when the variables will contain valid information. IN indicates that the variable has valid information when calling the function; OUT indicates that the variable will have valid information after the called function returns. See "pass by reference" and "pass by value" for related information.

#### Q 4.12 How can I get a specific folder's sector position? [top^]

A. Anonymous quoted :-

You may use ASPI or SPTI to read CD sector. Scan TOC to locate a specific folder descriptor (see ISO 9660 ). To send an ASPI command, you may use "SendASPI32Command" function from winaspi.dll, or use DeviceIOControl to send SPTI command.

### [15 Jan to 23 Jan 2005]

#### Q 5.01 How to change the background color of an Edit Box? [top^]

A. Gary R. Wheeler quoted :-

You can change the background color of an edit control in a dialog by handling the WM_CTLCOLOR message in the dialog:

class MyDialog : public CDialog {
//...
COLORREF _BkgColor;
HBRUSH   _BkgBrush;
};
BOOL MyDialog::OnInitDialog()
{
//...
_BkgColor = RGB(0,255,0);
_BkgBrush = ::CreateSolidBrush(_BkgColor);
}
HBRUSH MyDialog::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor )
{
hbr = CDialog::OnCtlColor(pDC,pWnd,nCtlColor);
if (pWnd()->GetDlgCtrlId() == IDC_MY_EDIT_CONTROL) {
pDC->SetBkColor(_BkgColor);
hbr = _BkgBrush;
}
return hbr;
}

In the OnInitDialog() handler for the dialog, we initialize the background color value and create a brush in that color. The WM_CTLCOLOR handler is called OnCtlColor. The edit control for which we want to change the color has the resource ID IDC_MY_EDIT_CONTROL. We set the text background to our background color using SetBkColor(), and the overall background for the control by returning the brush we created.

#### Q 5.02 How to increase the height of the header of a listcontrol?[top^]

A. Martin Koorts quoted :-

I've had a look at this, and can see no way - the CHeaderCtrl retrieved from the CListCtrl has facility for only adjusting the width of a column. You'll have to look at owner-draw.

#### Q 5.03 How to generate UNIQUE Key over the Network/Local Computer?[top^]

A. Martin Koorts quoted :-

The 'pattern' here is choosing whether to have;

1. unique IDs generated by a central authority (and relative to itself) - e.g. having an autoincrement ID in a database table, or similar -

or...

2. generate unique IDs that are absolute (using UuidCreate/UuidCreatSequential) - can be created anywhere and doesn't require contacting an authority.

Option a) in a distributed environment not only introduces a bottle-neck (consider many clients asking for IDs, or even ranges thereof, at the same time), but also in terms of performance cannot compete with client local GUID generation (network time typically cannot compete with local CPU/HW time).

Unless the GUID generation causes a technical barrier, or you require IDs with predictable values, I suggest you use it.

Also, you might want to design it such that you can afford to start using GUIDs now, and capitalise on this known, proven feature in your implementation; and at a later stage, if you still find the performance or size of the IDs too large, change it to something bespoke without compromising the design. In other words, IDs are opaque and of variable size.

#### Q 5.04 How to get file-size of a file? [top^]

A. DavidCrow quoted :-

OK, what's wrong with:

DWORD SizeOfFile( LPCTSTR lpszFile )
{
DWORD dwSize = 0;
HANDLE hFile;

hFile = CreateFile(lpszFile, 0, 0, NULL, OPEN_EXISTING, ...);
if (hFile != INVALID_HANDLE_VALUE)
{
dwSize = GetFileSize(hFile, NULL);
// you may want to use GetFileSizeEx() instead
CloseHandle(hFile);
}

return (dwSize);
}

showe quoted :-

Try:

CFile myFile(lpszFileName, CFile::modeRead);
int len = myFile.GetLength();

#### Q 5.05 Does anybody know of an API for digital cameras?[top^]

A. Mike Dimmick quoted :-

Well, there's the Still Image API[^].

A. Serge Krynine quoted :-

I think this code illustrates what you need:

void CShowHideMenuDlg::OnShowMenu()
{
}

{
// Remove and destroy the old menu
}

#### Q 5.07 Please give me an example of RegEnumValue?[top^]

A. ThatsAlok quoted :-

First, take a look at RegEnumKey. RegEnumKey looks like this:

LONG RegEnumValue(
HKEY hKey,              // handle to key to query
DWORD dwIndex,          // index of value to query
LPTSTR lpValueName,     // value buffer
LPDWORD lpcValueName,   // size of value buffer
LPDWORD lpReserved,     // reserved
LPDWORD lpType,         // type buffer
LPBYTE lpData,          // data buffer
LPDWORD lpcbData        // size of data buffer
);

Now some code snippet:

char szNameOfKey[200];//Buffer
DWORD dwBufferSize=200;//Buffer Size
DWORD dwIndex=0;
CStringArray arrOfKeys;

Now, enumerate the HKEY_CURRENT_USER using RegEnumKey.

 while(RegEnumKey(HKEY_CURRENT_USER, //
dwIndex++, //Index of Key to be Retrive
szNameOfKey,//Buffer of Key
dwBufferSize,//Buffer Size
NULL,//as documented in MSDN
NULL,//We don't need this right
NULL,//So no need of it
NULL)!= ERROR_NO_MORE_ITEMS)
{
//add New Found Key to array
//Restucture the size of Buffer as it modified during
//Enumeration
dwBufferSize=200;
}

//Now arrOfKeys Hold all the Enumerated Key

#### Q 5.08 How to disable/enable OK button in a property sheet?[top^]

A. R.selvam quoted :-

This link will help in this regard :- Hacking the CPropertySheet[^].

#### Q 5.09 How to get the serial number of a Compact Disc (CD)?[top^]

A. Dudi Avramov quoted :-

#### Q 5.10 How to check if remote computer exists? [top^]

A. DavidCrow quoted :-

How about NetServerGetInfo(L"Computer42", 100, ...)? It will return ERROR_BAD_NETPATH if the machine does not exist.

#### Q 5.11 How to create nested directories?[top^]

A. Chris Losinger quoted :-

CreateDirectory(top);
CreateDirectory(top + "\\subdir1");
CreateDirectory(top + "\\subdir1\\+subdir2");

#### Q 5.12 How to get HWND of a dialog box?[top^]

A. Ravi Bhavnani quoted :-

You can access its window handle by calling GetSafeHwnd() or its member variable m_hWnd.

#### Q 5.13 How can I know if the user is pressing on a button for more than 250 msec?[top^]

A. Gary R. Wheeler quoted :-

Create your own button class CMyButton, which subclasses the existing CButton. Add a handler for the WM_LBUTTONDOWN message to CMyButton. In the handler, post a notification to the parent dialog like this:

    WPARAM wParam = MAKEWPARAM(GetDlgCtrlID(),BN_PRESSED);
LPARAM lParam = (LPARAM)m_hWnd;

GetParent()->PostMessage(WM_COMMAND,wParam,lParam);

where BN_PRESSED is a notification code you've defined. In your dialog, add a handler for the BN_PRESSED notification. In the handler, start a timer (try using QueryPerformanceCounter). In your BN_CLICKED handler, get the value of the timer and compare the difference.

posted on 2006-01-13 09:23  henry  阅读(1559)  评论(1编辑  收藏  举报