|
If I have an LPCTSTR lpszString , how can I check if lpszString is empty ? Either , if is NULL , is correct lpszString == NULL ?
Thank you .
|
|
|
|
|
The best way is to make two checks:
if ((lpszString == NULL) || (lpszString[0] == 0))
{
[lpszString is NULL or empty ]
}
|
|
|
|
|
Thank you , does function .
|
|
|
|
|
if(!lpszString || !*lpszString){
}
"Real men drive manual transmission" - Rajesh.
|
|
|
|
|
In C and C++, strings are null-terminated. As such the last character will always be a NUL character (ASCII 0).
Consequently, any string (char*, const char*, LPTSTR, LPCTSTR etc.) can be checked for empty using:
LPCTSTR sz;
if (!sz[0]) { }
However, commonly you also need to check if the string pointer is null - this means that the pointer does not refer to a string at all, rather than that the string is empty:
LPCTSTR sz;
if (!sz) { }
Commonly, the two must be used together to check for empty or null:
if (!sz || !sz[0]) { }
|
|
|
|
|
Thank you all , I learned something here !
modified 2-Jan-19 3:54am.
|
|
|
|
|
You're welcome.
I should have mentioned that in the last case, order is important:
if (!sz || !sz[0]) { }
If sz is null , then !sz will evaluate true and the second won't be evaluated.
Otherwise, sz[0] will cause a memory access violation if evaluated on a null pointer.
(I also reordered the comment to reflect this).
|
|
|
|
|
Hi,
I'm trying to work through the example code in the MSDN DirectSound Programming Guide to enumerate sound devices.
When I run my app, the ComboBox which should list the available sound devices is for some reason empty.
Below is the Callback Procedure I've used for the Direct Sound device enumeration.
BOOL CALLBACK DSEnumProc(LPGUID lpGUID, LPCSTR lpszDescription, LPCSTR lpszDriverName, LPVOID lpContext)
{
HWND hCombo = (HWND)lpContext;
LPGUID lpTemp = NULL;
if(lpGUID != NULL)
{
if((lpTemp = (LPGUID)malloc(sizeof(GUID))) == NULL)
return TRUE;
memcpy(lpTemp, lpGUID, sizeof(GUID));
}
ComboBox_AddString(hCombo, lpszDescription);
ComboBox_SetItemData(hCombo, ComboBox_FindString(hCombo, 0, lpszDescription), lpTemp);
free(lpTemp);
return TRUE;
}
FYI Inspecting lpGUID during debugging reveals that the first time the if(lpGUID != NULL) is reached, it's value is 0 so the statement evaluates to FALSE, and lpszDescription points to the 'P' of "Primary Sound Driver". The call to ComboBox_AddString processes ok without returning CB_ERR or CB_ERRSPACE. The process repeats for the other available devices, but once it's finished the ComboBox remains empty!?
Below is my Callback procedure for the dialog containing the ComboBox. I've added a static text to display the total number of entries as a check, but this shows "Num Entries: 0" when I run the app. What am I missing here?
BOOL CALLBACK DLG_AudioDeviceSelectionProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hCombo, hEntryCountText;
int iCount;
TCHAR szBuffer[32];
switch(message)
{
case WM_INITDIALOG:
hCombo = GetDlgItem(hDlg, IDC_COMBO);
if(DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc,(VOID*)&hCombo) != DS_OK)
{
EndDialog(hDlg, TRUE);
return TRUE;
}
iCount = ComboBox_GetCount(hCombo);
hEntryCountText = GetDlgItem(hDlg, IDC_ENTRY_COUNT);
wsprintf(szBuffer, TEXT("Num Entries: %i"), iCount);
SetWindowText(hEntryCountText, szBuffer);
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDCANCEL:
case IDOK:
EndDialog(hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}
I'm using MS VC++ 2010.
I've worked through Petzold but I'm still essentially a Win API noob.
modified on Monday, April 11, 2011 12:57 AM
|
|
|
|
|
First of all, there is no break; after the case WM_INITDIALOG: block.
If this doesn't fix the problem, then get count of the combo box after each AddString() - put a breakpoint on it to make sure it's incremented.
If you still have problem, post here your code where you call AddString() .
|
|
|
|
|
Thank you for your response Hans.
I added the break; after the case WM_INITDIALOG: block. Thank you, this was an oversight. Unfortunately it has not fixed the problem.
I've now added a static int called iCount to the callback procedure where I call ComboBox_AddString() . I've used ComboBox_GetCount() to update iCount .
I've also added some error handling to the ComboBox_AddString() call.
When I put in a breakpoint here and debug, I see that iCount remains at 0 each time the code passes through.
Below is my revised code.
BOOL CALLBACK DSEnumProc(LPGUID lpGUID, LPCSTR lpszDescription, LPCSTR lpszDriverName, LPVOID lpContext)
{
HWND hCombo = (HWND)lpContext;
LPGUID lpTemp = NULL;
static int iCount;
if(lpGUID != NULL)
{
if((lpTemp = (LPGUID)malloc(sizeof(GUID))) == NULL)
return TRUE;
memcpy(lpTemp, lpGUID, sizeof(GUID));
}
if(ComboBox_AddString(hCombo, lpszDescription) == CB_ERR | CB_ERRSPACE)
{
MessageBox(hCombo, TEXT("Error Adding String To ComboBox"), TEXT("Error!"), MB_OK);
}
iCount = ComboBox_GetCount(hCombo);
ComboBox_SetItemData(hCombo, ComboBox_FindString(hCombo, 0, lpszDescription), lpTemp);
free(lpTemp);
return TRUE;
}
Is it something to do with the way I'm trying to pass the ComboBox handle to the DSEnumProc procedure when I initialize the dialog? I notice that the value of hCombo in the code below is different from the value in the code above when I debug.
hCombo = GetDlgItem(hDlg, IDC_COMBO);
if(DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc,(VOID*)&hCombo) != DS_OK)
{
EndDialog(hDlg, TRUE);
return TRUE;
}
Thank you again for your help
Paul
|
|
|
|
|
When you say (VOID*)&hCombo , what you're doing is passing the address of hCombo. But in your callback, you write
HWND hCombo = (HWND)lpContext;
So, you're doing one thing, but telling the compiler something else. Do you see what I mean? I could go further if you want.
|
|
|
|
|
Yes, I used (Void*)&hCombo and HWND hCombo = (HWND)lpContext as this was how it was written in the MSDN explanatory code snippets.
I think I understand what you mean though.
lpContext is a pointer which contains the address of hCombo when I pass it, so I need to dereference lpContext when I'm initializing the local hCombo in the callback, right?
I've tried HWND hCombo = (HWND)*lpContext; but the IDE says "Error: expression must be a pointer to a complete object type". Is it incorrect to declare, dereference, cast and initialize all in the one statement?
Thank you again.
Paul
|
|
|
|
|
Actually, it would be simpler to just keep your callback code the same, and write (Void*)hCombo . A HWND will fit into a pointer-size variable, which is what lpContext is. So keep the callback like you had it before: HWND hCombo = (HWND)lpContext;
|
|
|
|
|
Thanks Hans. It works.
I think I took MSDN's description of DirectSoundEnumerate too literally.
It says:
HRESULT DirectSoundEnumerate(
LPDSENUMCALLBACK lpDSEnumCallback,
LPVOID lpContext
)
Parameters
lpDSEnumCallback
Address of the DSEnumCallback function that will be called for each device installed in the system.
lpContext
Address of the user-defined context passed to the enumeration callback function every time that function is called.
So I assumed lpContext had to be a pointer, but since it's just being passed straight on to the callback function anyway, I guess it doesn't have to be.
Your help is greatly appreciated.
Best regards
Paul
|
|
|
|
|
Good ol' MSDN. God's gift to consultants.
BTW, Petzold was how I learned Win32 too. If you get tired of dealing with all that wndproc stuff, check out MFC; it's a very thin wrapper over Win32, and makes a lot of things easier.
Good luck.
|
|
|
|
|
THX
|
|
|
|
|
google for "file associations".
|
|
|
|
|
Hello,
I need to write simple application which will have main interface in default screen, which will be able to redirect just an output (simple animation) to the separate video output port (HDMI or DVI).
I want to use GDI+ to do that, however I don’t know how to obtain the DC of the output device.
I will be grateful for your advices or any articles about that.
Thank you a lot,
B.
|
|
|
|
|
Try this:
1. Use EnumDisplayMonitors[^] to enumerate the displays.
2. In the callback method ( MonitorEnumProc[^] ), use GetMonitorInfo[^] with MONITORINFOEX[^] to get the device name for the monitor (szDevice member)
3. Use CreateDC[^], specify "DISPLAY" for the lpszDriver parameter, the device name you got in step 2 for the lpszDevice parameter and NULL for the rest.
Of course you will want to filter out the one monitor/device you want to use. Hope this can direct you in the right direction.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> //TODO: Implement signature here<
|
|
|
|
|
Thank you a lot, this is exactly what I needed.
B
|
|
|
|
|
Yourwelcome.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> //TODO: Implement signature here<
|
|
|
|
|
Hello every one I have to draw red mark line in to list control having grid view to show invalidate entry Can any one tell how to draw it
|
|
|
|
|
Hi
You need to handle ListView custom draw and draw the line using the Device Context.
Find ListView custom draw article in code project.
Nitheesh George
http://www.simpletools.co.in
|
|
|
|
|
Thanks nitesh,
Rightnow I show rectangle having invalid entry with background color in custdraw but insted of background color I want to show line on that entry. So what I can do for it....
|
|
|
|
|
You need to handle the custom draw notification and draw the whole item in the control, using GDI (or GDI+) API calls.
For entries that are invalid, you can then draw a red line though then using MoveTo/LineTo.
For an example of a ListView custom draw, read this article[^]
EDIT: This article might be better that the C# one I originally posted... Using ListView control under Win32 API[^]
|
|
|
|
|