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
Answer
[10 Dec to 18 Dec 2004]
A. ThatsAlok quoted :-
If you are using MFC: this->ShowWindow(SW_MINIMIZE);
If you are using Win32 API based application: ShowWindow(hWnd,SW_MINIMIZE);
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.
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.
A. prcarp quoted :-
Look at WM_SIZE
:
wParam = SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED, etc.
lParam = cx -> lo word cy -> hi word
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.
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);
A. Mr.Prakash quoted :-
Make the parent window of each dialog as desktop window by calling GetDeskTopWindow()
.
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.
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.
A. Ryan Binns quoted :-
Use the pow()
function.
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.
A. Sujan Christo quoted :-
Have a look @ the following links, it may help you: Wikipedia - Keyword, Reserved word.
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.
A. Greeeg quoted :-
The GetPrivateProfileXXX
and WritePrivateProfileXXX
functions do the job for you.
A. Ryan Binns quoted :-
The tab order is simply the Z-order of the windows, so to change it use SetWindowPos()
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.
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.
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()
{
int Idx;
TCHAR ModName[_MAX_PATH];
if(!::GetModuleFileName(NULL,ModName,sizeof(ModName)) )
{
ASSERT(false);
return CString(_T(""));
}
CString LoadPath(ModName);
Idx = LoadPath.ReverseFind(_T('\\'));
if( Idx == -1 )
{
ASSERT(false);
return CString(_T(""));
}
LoadPath = LoadPath.Mid(0,Idx+1);
return LoadPath;
}
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.
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]
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.
A.DavidCrow quoted :-
Does NetUserGetInfo()
do what you require?
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.
A. DavidCrow quoted :-
How about GetWindowTextLength()
?
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.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if (CFrameWnd::PreCreateWindow(cs))
{
cs.dwExStyle |= WS_EX_TOOLWINDOW;
return TRUE;
}
return FALSE;
}
BOOL CMyApp::InitInstance()
{
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPED, NULL, NULL);
CMyDlg dlg(pFrame);
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{ }
return FALSE;
}
A. DavidCrow quoted :-
What about ChangeDisplaySettings()
?
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.
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!
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.
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.
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 :-
This page should be a big help for you...
e-sushi quoted :-
Guess I found some more useable stuff... Windows Driver Build Methods and Tools.
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()
.
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.
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]
A. DavidCrow quoted :-
To get the IP address of a machine, use gethostbyname()
.
A. SteveKing quoted :-
Try modifying CWnd::OnEraseBkgnd(..)
which erases the background.
A. Gary R. Wheeler quoted :-
Why not use the correct function: GetWindowModuleFileName()
.
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.
A. PJ Arends quoted :-
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.
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.
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"
).
A. Michael Dunn quoted :-
See MSDN.
A. Ravi Bhavnani quoted :-
Perhaps this[^] article will help?
A. Ravi Bhavnani quoted :-
See SetWindowPos()
and MoveWindow()
.
A. cedric moonen quoted :-
Go into the properties of your combobox -> 'Style' tab and select 'DropList' in the 'Type' combo.
A. DavidCrow quoted :-
Use SQLConfigDataSource()
.
A. k_dehairy quoted :-
Try using this member function of the dialog:
ModifyStyle(WS_CAPTION,0);
::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
To get the toolbar back:
ModifyStyle(0,WS_CAPTION);
::SetWindowPos(m_hWnd,HWND_TOP,0,0,cx,cy,SWP_SHOWWINDOW);
A. ThatsAlok quoted :-
Beginner's Tutorial - Using global hotkeys.
A. Michael P Butler quoted :-
ThatsAlok quoted :-
One more in addition:
A. Michael Dunn quoted :-
In your C++ code, do this:
extern "C"
{
#include "your_c_header.h"
}
A. ThatsAlok quoted :-
When you press Alt+F7, your Project.DSP will get modified.
A. Rajesh match quoted :-
Look for CFile::shareExclusive
in MSDN.
cmk quoted :-
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]
A. basementman quoted :-
CFont m_fArial;
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");
CListCtrl *m_pList = (CListCtrl*)GetDlgItem(IDC_LIST1);
m_pList->GetHeaderCtrl()->SetFont(&m_fArial);
The key here is to get a pointer to CListCtrl
's embedded Header control.
A. Ravi Bhavnani quoted :-
You could try porting this Unix example[^]. There's also some source here[^]. Also see this commercial source[^].
A. Michael P Butler quoted :-
Have a look at this list of examples[^].
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[^].
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.
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:
static DWORD WINAPI MyThread(PVOID lParam)
{
x *pX = (x *)lParam;
}
}................
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:
DWORD WINAPI MyThread(void);
};
...
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.
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.
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:
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.
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.
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.
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]
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.
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.
A. Martin Koorts quoted :-
The 'pattern' here is choosing whether to have;
- unique IDs generated by a central authority (and relative to itself) - e.g. having an autoincrement ID in a database table, or similar -
or...
- 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.
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);
CloseHandle(hFile);
}
return (dwSize);
}
showe quoted :-
Try:
CFile myFile(lpszFileName, CFile::modeRead);
int len = myFile.GetLength();
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()
{
CMenu mMainMenu;
mMainMenu.LoadMenu(IDR_MENU1);
ASSERT(mMainMenu);
SetMenu(&mMainMenu);
}
void CShowHideMenuDlg::OnHideMenu()
{
SetMenu(NULL);
::DestroyMenu(GetMenu()->GetSafeHmenu());
}
A. ThatsAlok quoted :-
First, take a look at RegEnumKey
. RegEnumKey
looks like this:
LONG RegEnumValue(
HKEY hKey, DWORD dwIndex, LPTSTR lpValueName, LPDWORD lpcValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData );
Now some code snippet:
char szNameOfKey[200];DWORD dwBufferSize=200;DWORD dwIndex=0;
CStringArray arrOfKeys;
Now, enumerate the HKEY_CURRENT_USER
using RegEnumKey
.
while(RegEnumKey(HKEY_CURRENT_USER, dwIndex++, szNameOfKey, dwBufferSize, NULL, NULL, NULL, NULL)!= ERROR_NO_MORE_ITEMS)
{
arrOfKeys.Add(szNameOfKey);
dwBufferSize=200;
}
A. R.selvam quoted :-
This link will help in this regard :- Hacking the CPropertySheet[^].
A. Dudi Avramov quoted :-
Check: Checking the serial Number of a CD.
A. DavidCrow quoted :-
How about NetServerGetInfo(L"Computer42", 100, ...)
? It will return ERROR_BAD_NETPATH
if the machine does not exist.
A. Chris Losinger quoted :-
CreateDirectory(top);
CreateDirectory(top + "\\subdir1");
CreateDirectory(top + "\\subdir1\\+subdir2");
A. Ravi Bhavnani quoted :-
You can access its window handle by calling GetSafeHwnd()
or its member variable m_hWnd
.
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.
Points of Interest
Nothing much to say, idea and design are taken from Mr. Michael Dunn (MS Visual C++ MVP) CPP Forum FAQ article.
Please keep in touch for more article on this series.
Special Thanks
- My parents.
- All active contributors/members of the Visual C++ forum [CodeProject], as without them this article wouldn't have seen day light.
Other Articles of this Series
History
- 25 June 2005: Posted on CodeProject.
- 21 June 2005: Started working on this article.