Sorry, I should have been more specific. Rather than general containers (some of which, you're right, have to use the find function) the map/set and the new unordered ones. They do have a member function, so could quite easily do the same thing as cbegin()/cend(), at least I can't see any reason why not. For the not-to-const, I don't exactly follow. Gonna go play a bit to see what you mean. Thanks, CraigL
Craig Longman
Posts
-
Why is there no cfind() in the std containers? -
Why is there no cfind() in the std containers?I know that the cbegin()/cend() and such methods were implemented to allow for easy const type inference, but I'm curious as to why there wasn't any equivalent added for find()? Also, there isn't a real easy way to "trick" auto into inferring a const version, is there? Although it doesn't show itself as non-mutating in code, all I can think to do is use a const ref/pointer to the container, which would "force" a const_iterator return, right? However, I really like how cbegin() clearly states it's const-ness, right where it's being used. I've searched around off and on, looked through the (what I think is) the original proposal paper, nothing seems to hint as to why poor find() got the const-shaft. Curious, CraigL
-
Basic C++ String QuestionStefan63 wrote:
1. Whether this works or not is compiler dependend - a compiler is free to evaluate the left or right side of an || operator in whatever order it likes!
Erm... hold on a sec here... Short-circuiting IS mandated, and can only work if it's evaluated in order. It's always true for PODs. The only caveat is, if it is a class, and that class has an overloaded && or || operator. Then, both sides will be evaluated, so that the compiler can pass the element on the right hand side as a parameter. One (very) good reason to never, ever overload them. At least, this is the way I understand it, and I can't imagine anything undoing that, as tons of code that did this:
if( pszString != NULL && *pszString != '\0' )
would randomly crash if *pszString was evaluated first. Course, in this example the actual comparisons can be removed, but I was trying to be explicit. N'est pas? -- CraigL
-
Now I know why people use makefilesI just did it again in v9 and when All Configurations is selected, it replaces them all. I guess it was fixed.
Richard MacCutchan wrote:
Hmmm, I would have thought that "Visual Studio" is closest; this question has almost nothing to do with C, C++ or MFC.
Indeed, I guess I didn't actually point out that the Visual Studio way at the bottom escaped my attention. =) Thanks anyway, clearly something resolved in the next version, another good reason to upgrade I guess. Just gotta be careful for the time being.
-
Now I know why people use makefilesEven with only one project, in VS v9, if I select all targets/platforms and put in a preprocessor directive, it simply removes all the current directives and replaces it with what I typed in. This doesn't happen this way for you? Sorry about the wrong forum, I looked, but the closest I saw was this one having a description of "C, Visual C++ and MFC" and thought it was the closest.
-
Now I know why people use makefilesAlthough this is a Visual Studio specific thing, it seems this forum (based on the help info from the website) is for Visual C++ questions/issues. Visual Studio project handling has gone so far downhill since 6.0, it's astounding. Once again, I've been stupidly bitten by the thinking I can apply an All Config/All Target parameter (preprocessor directive in this case) forgetting that it will blow away all the other carefully crafted per Config/Target values. This seems so stupid, I feel I must be missing something obvious? I mean, if I change something project wide like precompiled headers, it doesn't destroy the individual file settings. Has VS v9 really lost the ability to properly handle file/config/target/global settings like preprocessor directives? Please tell me there is something obvious that I should click/check/choose in order to have a global item simply be added, rather than something so remarkably wrong as removing all the specific items and replacing them? Sorry if this sounds like a rant, but I just lost ALL the target specific settings for all 6 projects in my solution because I had to add _CRT_SECURE_NO_WARNINGS to all targets/configs. I have them in SVN, but still, there were other changes I've made tonight that I will lose. And given how advanced VS v9 is, it seems insane that I'd need to wear out my mouse battery with all the individual clicking and pasting that doing it one at a time would take. Thank goodness for :1,$s/(XX)/\1;YY/ in vim... But why has this gotten so very, very wrong since VS v6? Hoping to find out I've just stupidly overlooked something,
-
Bring bits of old MFC apps into an ATL appI have a app using ATL for both the COM and the Service pieces. I have recently had need to bring in some old code that archives itself via CArchive (MFC). I don't seem to be able to hack up the right choices/orders of headers for getting the ATL classes like CAtlServiceModuleT while still have the MFC class CArchive available. The only docs I've found so far, deal with including the MFC bits first, then the ATL bits. But that defines _AFX, and so the ATL bits leave out items like CAtlServiceModuleT. Is there some way to make ATL the "main" library and then pull in the MFC bits later? Short of #undef'ing too many things and/or pulling bits out of header files, etc. Thanks, CraigL
-
CComContainedObject QuestionI have a plugin that I'm developing that is used in a COM environment. The issue is, I seem to be able to readily obtain an pointer to a base class of my class, but I'm unable to figure out how to get a pointer to my main class. Here is my class:
class ATL_NO_VTABLE Plugin :
public CDXBaseNTo1,
public CComCoClass< Plugin, &CLSID_Plugin >,
public IDispatchImpl< IPlugin, &IID_IPlugin, &LIBID_MAINLib >,
#if(_ATL_VER < 0x0300)
public CComPropertySupport< Plugin >,
#endif
public IObjectSafetyImpl2< Plugin >,
public IPersistStorageImpl< Plugin >,
public ISpecifyPropertyPagesImpl< Plugin >,
public IPersistPropertyBagImpl< Plugin >,
public CSFVideoPlugin< PLUGINPROPS >The
CSFVideoPlugin
is derived from theISfExchangeProps< PLUGINPROPS >
interface. Then, in another are of the plugin environment, the Property Page to configure it, I can do the following:CComQIPtr< ISfExchangeProps< PLUGINPROPS >, &IID\_ISfExchangeProps > pxPlugin( m\_ppUnk\[ 0 \] );
This part all works fine, and calls into the
pxPlugin
work fine. When inside a method call there, the debugger shows[ATL::CComContainedObject<Plugin>]
as the first "member" ofthis
, so the relationship is known, or so it would seem. But calls like this return a completely bogus pointer:CComQIPtr< Plugin, &IID\_IPlugin > pxPlugin( m\_ppUnk\[ 0 \] );
The memory is in the same basic area, but the values are all messed up, and in fact setting them on occasion can/will crashes. I can't figure out how to query for that CComContainedObject interface. Given that even the debugger has enough information to track it down though, clearly it must be. Any help would be greatly appreciated. If I haven't provided a piece of information that would be useful, please let me know. Thanks, CraigL
-
"Simple" capture pixel under mouse routine...I'd really have thought after so many years of being a graphical OS, this wouldn't be so hard... I'm trying to make a "simple" button that when clicked, allows the user to select a pixel on the screen to choose a colour. Almost everything is _finally_ working OK, I have a mouse hook in to commandeer the mouse entirely (no UAC involved even!?!) and I have a timer to grab the current pixel under the cursor. Not the simplest to accomplish, but eventually I figured it out. Even managed to figure out how to swallow the clicks so they don't get passed on. Now, I'm trying to turn the cursor into an eyedropper while I have the mouse so it's clear where the user is hovering over... SetCursor seems entirely ineffective. I set it with a cursor (one of the defaults from 'Add->Cursor' in the resource manager), confirmed it's loaded correctly, but nada... I can't tell if SetCursor is going to work to hold it, as the cursor never even changes. I have verified that the cursor is successfully loaded, well, verified that a non-NULL handle is returned, but still it doesn't seem to change when I set the cursor. I've also tried "resetting" the cursor to NULL with a call to
::SetWindowLong( m_hWnd, GCL_HCURSOR, (LONG)NULL )
, but it seemed to make no difference. Clearly it's possible, as every fourth program has a colour picker doodad it seems, but what hoops does one have to jump through? Do I really have to create a fake window, copy the screen DC, and proceed from there? Pointers/advice appreciated. Thanks, CraigL -
CImage and transparencyOK, I stumbled upon the
::LoadImage()
after thinking there must be a function more up-to-date that::LoadBitmap()
, and it lets me load a DIB from a resource, and then::GetObject()
gives me the bits. Thanks, CraigL -
CImage and transparencyI can see that being a problem if I had an alpha channel in the
zSwatchImage
. And at one point I did, so I guess I'd expect the behaviour I saw. But it's absurd to me that an "alpha blend" function can't take a 24bit image and "do the right thing" by copying it will the alpha channel opaque. Especially when you TELL it what the alpha value to copy with should be. If it isn't there, you'd think it would use the alpha provided as the source alpha, not just the blend alpha. But to take a 24bit image and assume the alpha is zero? And, I had thought thatCImage
did use GDI+, so the 24 -> 32 bpp copy would make sense. I guess I just expect too much fromCImage
. Course, now I'm having fun trying to get the bits directly from a BMP loaded via::LoadBitmap
... I guess graphics never really was a win32 strong point. Thanks for the reply. Normally, I totally exclude win32 APIs wrt image handling, just needed the BMP to use the easy way one can put it on a button. This exercise has just cinched that opinion even more =) -
CImage and transparencyI have a button that I want an image in, a basic colour swatch. I liked the idea of having a partially transparent shadow around it, so in GIMP, I created a 32 bit BMP with the desired alpha shadow, and a white, totally non-transparent square in the middle. The intention was to fill the white area in with the colour that the user chooses. Sounds simple enough. So, the basic code is such:
HDC hDC;
HANDLE hOldBmp;
HBRUSH hBrush;
LOGBRUSH zLogBrush;HBITMAP hColourShadowBmp_ = ::LoadBitmap( hInst, MAKEINTRESOURCE(IDB_COLOUR_SHADOW) );
zLogBrush.lbStyle = BS_SOLID;
zLogBrush.lbColor = RGB( m_Props.uiRed, m_Props.uiGreen, m_Props.uiBlue );
zLogBrush.lbHatch = NULL;hBrush = ::CreateBrushIndirect( &zLogBrush );
CImage zFinalImage;
CImage zSwatchImage;zFinalImage.Attach( hColourShadowBmp_ );
zSwatchImage.Create( 20, 20, 24 );hDC = zSwatchImage.GetDC();
::SelectObject( hDC, hBrush );
::Rectangle( hDC, 0, 0, 20, 20 );
zSwatchImage.ReleaseDC();hDC = zFinalImage.GetDC();
zSwatchImage.AlphaBlend( hDC, 2, 2, 255 );
zFinalImage.ReleaseDC();hOldBmp = (HANDLE)
::SendMessage( ::GetDlgItem( m_hWnd, IDC_COLOUR ),
BM_SETIMAGE,
(WPARAM)IMAGE_BITMAP,
(LPARAM)zFinalImage.Detach() );::DeleteObject( hBrush );
All I end up with is the source shadow image, with a lovely fully transparent square where the swatch should be. I know the swatch painting is working, as I can send that image and get the colour square I expect. Yet nothing I do seems to be able to make the colours get transferred. Crazily enough, the alpha is, if I set the alpha in the
AlphaBlend()
call to 0, I get the original shadow image unchanged. So I know that it is modifying the alpha channel properly at least. The source is opaque, so no amount of pre-multiplying will help. FWIW, I also tried making thezSwatchImage
a 32 bit with alpha, but it made no difference. The only solution I can see now is jumping into the bits for the shadow image and changing the RGB values to what I want. But surely I'm doing something wrong? It's hard to believe that a simply blend like this fails. Thanks, CraigL -
What is it with HBITMAPs?I've been working a lot with bitmaps for GUI uses lately, and frequently have been frustrated. Normally, I just fall back to using a CImage class when I have any actual work to do on the image, but now I'm trying to understand what is going on, and I'm confused. I have a button that I want to use coloured bitmap on instead of text (in Win7). So, here is what I tried first:
HBITMAP hBmp = ::CreateBitmap( 21, 21, 1, 24, NULL );
HDC hDC = ::CreateCompatibleDC( NULL );
::SelectObject( hDC, hBmp );
::SelectObject( hDC, hBrush ); // made from ::CreateBrushIndirect()
::Rectangle( hDC, 0, 0, 20, 20 );
::DeleteDC( hDC );
::SendMessage( hWnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp );But I just get a black square. Sized correctly, but black and the brush was created as white. MSDN et al. say that
::CreateCompatibleDC()
when provided with NULL creates a memory DC compatible with the screen. To me, this means something that is (in my case) a 24 bit colour DC. Reading more of MSDN, they indicate that for performance reasons, it is suggested to use::CreateCompatibleBitmap()
to create colour bitmaps. So, I tried this instead:HDC hDC = ::CreateCompatibleDC( NULL );
HBITMAP hBmp = ::CreateCompatibleBitmap( hDC, 21, 21 );
::SelectObject( hDC, hBmp );
::SelectObject( hDC, hBrush ); // made from ::CreateBrushIndirect()
::Rectangle( hDC, 0, 0, 20, 20 );
::DeleteDC( hDC );
::SendMessage( hWnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp );This gives me a white image on the button, great, I have a bitmap that works. However, changing the colour produces some silly, apparently monochrome, dithered bitmap on the button. Which leads me to believe that the DC being created is, in fact, not compatible with my screen. So I tried this:
HDC hDC = ::CreateCompatibleDC( ::GetDC( m_hWnd ) );
But get exactly the same result, a silly monochrome dithered version. What exactly does 'compatible' mean then? Short of going through the whole rigmarole of creating a DIBSection, how does one actually create a usable colour bitmap to draw on and send to a button? I must be missing something, I can't imagine that regular bitmaps are this useless, are they? Thanks, CraigL
-
Custom Draw confusionI'm trying to figure out how to remove the dashed focus cue from around one of my controls, a track bar. Based on the documentation on MSDN for custom drawing, here: http://msdn.microsoft.com/en-us/library/ff919569(v=VS.85).aspx#CustomDraw_DrawingItemsYourself I've set up the following in the parent window
NM_CUSTOMDRAW
handler:NMCUSTOMDRAW* pzCustomDraw;
LRESULT lResult = CDRF_DODEFAULT;
switch( iID )
{
case IDC_FONTSIZE_SLIDER:
case IDC_OFFSET_X_SLIDER:
case IDC_OFFSET_Y_SLIDER:
case IDC_CHOOSECOLOUR:
pzCustomDraw = reinterpret_cast< NMCUSTOMDRAW* >( pzNMHdr );if( pzCustomDraw->dwDrawStage == CDDS\_PREPAINT ) {
// lResult = CDRF_SKIPPOSTPAINT;
lResult = CDRF_NOTIFYITEMDRAW;
}
else if( pzCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT )
{
lResult = CDRF_SKIPPOSTPAINT;
}break;
}
bHandled = TRUE;
return lResult;
The MSDN article linked above states: CDRF_SKIPPOSTPAINT - The control will not draw the focus rectangle around an item. But doesn't indicate that the dwDrawState is anything other than the
CDDS_PREPAINT
, however as you can see I tried both forCDDS_PREPAINT
andCDDS_ITEMPREPAINT
. Neither of these actually do anything. The result is set correct, and returned, but the control still draws the focus cue. I'm thinking that the documentation just fails to indicate that this only works on list-view and tree-view controls, or can someone see something I'm doing wrong? Thanks, CraigL -
Getting DBLCLK MessagesAh... excellent, thank you. I will try that, even though I did end up emulating double click. I thought there was likely an issue with trying to set a CS_XXX when all the others seemed to be WS_XXX or WS_EX_XXX, but somehow never tracked down the
SetClassLongPtr
functions. Thanks, CraigL -
Getting DBLCLK MessagesI have a dialog box, with a few sliders/trackbars on them. Some of them are going to be used to represent a +/- variance, so they'll start off in the middle, and go - to the left, + to the right. Everything fine so far. But what I want to be able to allow is to double click on the thumb-thingie and have the slider reset to it's middle or zero position. To that end, I've made a little subclassing class, in the ctor, I do the following:
ZSlider( HWND hParentWnd, int iItemID )
: hParentWnd_( hParentWnd )
,iItemID_( iItemID )
{
hWnd_ = ::GetDlgItem( hParentWnd_, iItemID_ );bValid\_ = ::SetWindowSubclass( hWnd\_, &ZSlider::StaticWndProc, (UINT\_PTR)WM\_APP\_SLIDER\_DBLCLK, (DWORD\_PTR)this );
}
...
static LRESULT CALLBACK StaticWndProc( HWND hWnd,
UINT uiMsg,
WPARAM wParam,
LPARAM lParam,
UINT_PTR puiID,
DWORD_PTR pdwRefData )
{
reinterpret_cast< ZSlider* >( pdwRefData )->WndProc( hWnd, uiMsg, wParam, lParam );return ::DefSubclassProc( hWnd, uiMsg, wParam, lParam );
}
This all seems to work great, I get the
WM_LMOUSEDOWN
messages, but I never receive a DBLCLK message. I think I'm passing the messages on fine, so I dug deeper and found that windows need to be created with theCS_DBLCLKS
style to receive the messages, so in the ctor I added:::SetWindowLong( hWnd\_, GWL\_EXSTYLE, ::GetWindowLong( hWnd\_, GWL\_EXSTYLE ) | CS\_DBLCLKS );
With both
GWL_EXSTYLE
andGWL_STYLE
. But neither seemed to make any difference. Is theCS_DBLCLKS
add-able at runtime, and if so, how? Or, am I not forwarding the messages properly so the DBLCLK just never gets registered? Or, in typical fashion, are these controls/windows just 'unique' and I'll need to implement some kind of custom double click handling. Any advice greatly appreciated. Thanks, CraigL -
Resizing a windowThanks, but that actually wouldn't have helped. The point was I didn't know where the host app was calling in. So, short of adding in a call like that to every method, as well as every method of every base class, there was no solution that I could program in. Breaking on MyDLL.dll!* is pretty much the only solution. Even the Class::* didn't work, as the parser failed to find some of the templatized based classes. Again, manually going through each and every base and adding breakpoints in would have caught them for each class that I tediously added them all in, but I was really hoping to get a better idea of when anything was called by the host app.
-
Getting Symbols WorkingHehehe... then you've been lucky. =) However, the symbols aren't much good for that, but they are very helpful to see why you're being called. I'm currently working on a plug-in, and I don't always know why the host app is doing something, and have some named function trace can be very helpful indeed.
-
Getting Symbols WorkingYou might be thinking of checked builds, when there all the parameter validation/integrity is checked in all the system calls. The symbol files are relatively freely available. Microsoft has symbol servers that you can point VS to (http://referencesource.microsoft.com/symbols) or you can download the symbols for either retail or checked from here: http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx Unfortunately, I can't seem to get the common ones like user32.dll recognized. Some of the more esoteric ones seem to load fine though. Although both my build and the install seem to be for Win7 v6.1 build 7600, for some reason it's not matching checksums. I guess I'll probably end up setting up an XP machine to do this if I need it, I guess Win7 is perhaps too new to have proper symbols available. Or the OEM ones are different, or something. Frustrating.
-
Resizing a windowWell, I did finally manage to figure it out. The containing app was moving it, but using the
IPropertyPageImpl::Move
method. Why they didn't see fit to call itMoveWindow
like every other single thing in windows, is beyond me. If I'd been able to figure out how to configure a breakpoint for whenever my DLL was entered, I'd have found it in no time.CraigL