|
Hi,
I did not know that (thanks for the tip!), but I tried what you suggested with no good results. Although I have to say that I launch multiple instances of the same thread (look at my code), so I wonder if it's not failing when the thread function gets executed the 2nd time...
I'm sorta new to threads, just trying to figure out how they work...
Thanks again!
|
|
|
|
|
Guess more context is needed to help you find the problem. For instance, are you sure that CValidateurDlg exits only when all threads launched by OnButton1 have terminated? The m_hThread variable suggest you only keep track of the last thread launched.
Joaquñin M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
This doesn't really answer your question, but here's the basics of a little class that can be used for simple locks:
CX_Lock::CX_Lock(CRITICAL_SECTION *cs){
EnterCriticalSection(cs);
m_pCriticalSection = cs;
}
CX_Lock::~CX_Lock(){
LeaveCriticalSection(m_pCriticalSection);
}
Now, for a class whose, say, accessor functions should be guarded, declare a member CS:
CRITICAL_SECTION m_cs;
And don't forget to call InitializeCriticalSection(&m_cs); in the constructor and DeleteCriticalSection(&m_cs); in the destructor.
Then inside a block of code in a memeber fn you just declare a local lock object like so:
DWORD MyClass::GetMyMemberVar()
{
CX_Lock lock(&m_cs);
return m_dwMyMemberVar;
}
And voila, you've serialized thread access to the code in the block where the lock object has scope.
This has the advantages of exception safety (unwinding the stack will call the lock's dtor and exit the CS) and less code to muck with.
As an additional nice touch, declare the default ctor private (so people will use the class properly).
Not sure where I stumbled on this - I thought the MFC had an equivalent, but not sure.
|
|
|
|
|
Try out locking with the primitives:
CRITICAL_SECTION lock;
in the ctor: ::InitializeCriticalSection(&lock);
locking: ::EnterCriticalSection(&lock);
unlocking: ::LeaveCriticalSection(&lock);
in the dtor: ::DeleteCriticalSection(&lock);
I often heard about porblems with MFC-sync-Classes.
mfg HintiFlo
|
|
|
|
|
How to set a bitmap as a dialog background ?
Thanx.
|
|
|
|
|
It goes along this:
Class CYourDlg: public CDialog{
...
CBitmap m_bitmap_background;
BITMAP m_bmInfo_background;
...
};
BOOL CYourDlg::OnInitDialog()
{
...
m_bitmap_background.LoadBitmap(IDB_BACKGROUND);
::GetObject(m_bitmap_background,sizeof(BITMAP),&m_bmInfo_background);
...
return TRUE;
}
BOOL CYourDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
HBITMAP* pBmpOld=(HBITMAP*)::SelectObject(dcMem.m_hDC,m_bitmap_background);
for(int y=rect.top;y<rect.bottom;y+=m_bmInfo_background.bmHeight){
for(int x=rect.left;x<=rect.right;x+=m_bmInfo_background.bmWidth){
pDC->BitBlt(x,y,m_bmInfo_background.bmWidth,m_bmInfo_background.bmHeight,
&dcMem,0,0,SRCCOPY);
}
}
::SelectObject(dcMem.m_hDC, pBmpOld);
return TRUE;
} This is for a tesellation effect (sort of like background images in HTML). Easy to adapt it to your specific needs.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
|
I have a PString class that derives from CString. In it, I overload the + operator so I can add a PString and long variable to give me a new PString. It works fine in VC 5.0, but while converting to VC 6.0, I get a C2666 error saying it cannot determine which overloaded + to use.
Here is the code segment:
PString strTemp1 = "abc";
long lTemp1 = 123;
PString strTemp2 = "def";
(1) strTemp2 = strTemp1 + strTemp2; // works fine.
(2) strTemp2 = strTemp1 + lTemp1; // C2666 error.
(3) strTemp2 = +(strTemp1, lTemp1); // no error.
(4) strTemp2 = ::operator +(strTemp1, lTemp1); // no err
class PString : public CString
{
public:
....
PCSGENRL_EXP_TYPE friend PString operator +( const PString& string1, const PString& string2 );
PCSGENRL_EXP_TYPE friend PString operator +( const PString& string, TCHAR ch );
PCSGENRL_EXP_TYPE friend PString operator +( TCHAR ch, const PString& string );
PCSGENRL_EXP_TYPE friend PString operator +( const PString& string, LPCTSTR lpsz );
PCSGENRL_EXP_TYPE friend PString operator +( LPCTSTR lpsz, const PString& string );
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const long& value);
PCSGENRL_EXP_TYPE friend PString operator +(const long& value, const PString& string);
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const double& value);
PCSGENRL_EXP_TYPE friend PString operator +(const double& value, const PString& string);
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string,const int& value);
PCSGENRL_EXP_TYPE friend PString operator +(const int& value, const PString& string);
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, const ULONG& value);
PCSGENRL_EXP_TYPE friend PString operator +(const ULONG& value,const PString& string);
Why does line (2) give an error, while lines (3) and (4) give no compile error? Aren't they the same instruction?
Any help would be appreciated.
Pat
|
|
|
|
|
it probably can't decide between long and int for the second value.
try this : strTemp2 = strTemp1 + (long)lTemp1;
=c
Smaller Animals Software, Inc.
http://www.smalleranimals.com
|
|
|
|
|
I tried
strTemp2 = strTemp1 + (long)lTemp1;
and it still gives the C2666 error.
I agree that it probably can't decide the type of that second value, but I have tried changing the overload definitions to
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, const long& value);
and
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, long& value);
and
PCSGENRL_EXP_TYPE friend PString operator +(const PString& string, long value);
From what I have read on this error in the help pages, if the compiler can't find an exact match, then it will try to do some conversions to get a match.
You would think that one of the above 3 overloaded definitions would give an exact match so the compiler wouldn't have to do any conversions. But I guess I am missing something. I assume the first argument is fine because I can add a PString and a PString. So it must be something with the second (long) argument, but I can't figure it out.
Pat
|
|
|
|
|
Amusing problem! First, your line (3) is probably not the same as (2), but rather a very different expression that by chance happens to compile. If I'm right, the compiler interprets it as a call to unary operator + applied to strTemp1, lTemp1 , which in turn is parsed as the sequencing operator , applied to strTemp1 and lTemp1 . In a nutshell, (3) is parsed as:
strTemp2 = +(strTemp1, lTemp1)
strTemp2 = +(lTemp1);
strTemp2 = lTemp1; For this analysis to hold water, some conversion from long to PString must exist. Otherwise I'm wrong (please confirm this). You can also check this hypothesis simply by printing out the result of (3) and seeing if it corresponds to the "stringed" value of lTemp1 .
Then, if (3) actually is ruled out, we are left with solving the riddle of (4) compiling fine and (2) producing a C2666 error. IMHO, the only way for (4) not being equivalent to (2) is that your addition operators are defined in a namespace other than the global namespace, and the :: in ::operator + is making the difference by narrowing the set of addition operators applicable. Again, you're the one who can confirm or deny this.
So, if (3) and (4) give no error for the reasons I said (which I'm far from sure), then probably (2) fails legally to compile due to an overabundance of applicable operators and conversion. See this Microsoft article for an analysis of a problem resembling yours.
Why VC++ 5.0 compiled fine and 6.0 complains? Well, maybe is 6.0 being more standard compliant with respect to Koening lookup, who knows.
As you see, this is just a chain of speculations. Some of them you can easily check out (please inform back).
Also, I suggest you post this problem to comp.lang.c++.moderated for more authoritative opinions.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks Joaquin,
You are right on in your analysis. The result of line (3) is the value of lTemp1 "stringed", exactly as you broke it down. In fact, I thought my overload of PString + PString was working, but I stepped into the code with the debugger, and it wasn't going to my PString overload of '+', but to the CString overload of '+'. So it was doing a PString to CString conversion for me behind the scenes..
In researching this problem, the only thing I could come up with is that there are 2 ways to override the operators. One is to have a 'friend' function within the class. The other is to define it globally, outside the class. So I took my + overrides out of the PString class and defined them globally. Now things seem to be working just fine. I guess there was some scope issues.
BTW, in reading about the C2666 error, I did read that the reason behind errors like this is because Microsoft is implementing/enforcing more of the accepted C++ standards, just as you speculated.
Thanks for your analysis on this one.
Pat
|
|
|
|
|
I use following export for getting pointer on class derived from CListCtrl:
extern "C" void APIENTRY ExportToListCtrl(CBaseListCtrl *pBaseList) {};
Dll should fill data that it gathers into that list control, and actually it does the job, but when i build it as Release, list control doesnt show any results (all dlls functions for filling it works, but none of the data are shown)! I tryed the same using HWND for dll function parameter and attaching HWND to CBaseListCtrl that is declared inside dll and it worked, but the problem is that i desperatly need to use it trough *pBaseList as CBaseListCtrl has some CListCtrl functions overided as it allso fills some of its own internal structures. Dll is loaded dynamicaly (LoadLibrary(), GetProcAddress()).
Anyone knows how to make it work? Plz?
|
|
|
|
|
Most problably you're expriencing problems with different runtime library versions at the DLL and the calling program. Make sure both parts match at this point (Settings -> C/C++ -> Code generation -> Use run-time library: )
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Is there a way to align text in a status bar pane? I need to right align one of the panes in my status bar and I also need to know how to include a tool-tips type display when the pane is scrolled over. Any help is appreciated.
Thanks
|
|
|
|
|
Hi all, I am trying to make a custom drawing package in an MDI app. I have managed to load a bitmap into the child window using OnDraw and the CDC* pDC. I have also managed to get it to draw various lines to the screen when the users chooses the appropriate menu (yay ). However, these lines are drawn onto the CDC* pDC, is this the best way (I am getting flickering upon resizing of the child window)? or can you draw onto the CBitmap itself? The main focus of my problem is the fact I need to have low-level access to the pixel colours (in Delphi I was using scanline to scan whole lines of them into a PByteArray) so that I can change the ones that interest me, and leave the ones that don`t. Finally, what would be the best way to go about creating a layered approach, so that when I draw the lines etc. I don`t actually affect the underlying bitmap? would creating a new DC and drawing onto this, before outputting to the screen solve this? Anyway, I appreciate any help you could give on this guys,
Thanks, Alan.
AEGC
|
|
|
|
|
Hi,
for the flickering problem you may use a memory device, a bitmap in memory that you attach to a CDC, then from thisd CDC you copy over the CDC* pDC. else you can, before drawing access to the "screen bitmap" and use it... but I've never do It. There are good tutorial in the Graphics section who may contain theses information
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
|
|
|
|
|
Hi all, I am trying to make a custom drawing package in an MDI app.
I've done the same thing and pretty much had to learn how to do it as I went. If you're using GDI ( i.e. not GDI+), buy Windows Graphics Programming by Feng Yuan. Hell, buy it anyway, I still refer to it .
I have managed to load a bitmap into the child window using OnDraw and the CDC* pDC.
First things first. Do NOT use CBitmap, it is a device dependant bitmap. In order to be able to edit and save differing bitmap bit depths instead of just ones the same depth as the screen res, use a DIBSection wrapper like the one Chris Maunder wrote which is in the bitmaps section on the site.
I have also managed to get it to draw various lines to the screen when the users chooses the appropriate menu (yay ). However, these lines are drawn onto the CDC* pDC, is this the best way (I am getting flickering upon resizing of the child window)? or can you draw onto the CBitmap itself?
The only way to draw onto a bitmap is through a CDC unless you're planning to access the bits directly. As has been said, you fix the flicker by drawing to a memory DC and then drawing direct to the screen in one blt. I also killed OnEraseBackground because I was drawing over the whole surface myself anyhow, and that goes a long way to killing flicker.
The main focus of my problem is the fact I need to have low-level access to the pixel colours (in Delphi I was using scanline to scan whole lines of them into a PByteArray) so that I can change the ones that interest me, and leave the ones that don`t.
Using a DIBSection solves this problem - you will have access to the underlying bits in order to do whatever you pretty much like. You'll figure this out quickly anyhow, but I'll mention that Windows stores colours in BGR format.
Finally, what would be the best way to go about creating a layered approach, so that when I draw the lines etc. I don`t actually affect the underlying bitmap? would creating a new DC and drawing onto this, before outputting to the screen solve this? Anyway, I appreciate any help you could give on this guys,
In that case you could store the lines drawn in a path and actually draw them to the screen DC instead of the one holding the original bitmap. I did something like this for the line/shape tools ( where you stretch out a shape and it doesn't become a permanent addition until you let go of the mouse ) -> when the mouse button was pressed I started drawing onto the memDC before blting it to the screen, when you lifted the mouse I drew to the DC that held the bitmap, thus making a permanent change.
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
|
|
|
|
|
Thanks for responses guys. I have used a memDC to draw on and then blt it to the screen CDC*, however, I still have flicker (only when resizing the window, I can move the child about and its fine), I think it may be something to do with OnEraseBackground do you think you can tell me how to kill it (do I just override it and then fail to do anything in the function call?). Many thanks again for the responses I got, they were superb.
Cheers,
Alan;P
AEGC
|
|
|
|
|
You should simply return TRUE to indicate that you've handled the message, don't do anything else or call the base method.
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
|
|
|
|
|
I used the ON_UPDATE_COMMAND_UI message in a DialogBar to display button, this fonction do nothing. It is only usefull to avoid my DialogBar to grayed my button so the message map look like this
BEGIN_MESSAGE_MAP(CVBurnBar, CDialogBar)
ON_UPDATE_COMMAND_UI(IDC_Up_Normalize_AxisY, OnUpdateButton)
ON_UPDATE_COMMAND_UI(IDC_Bottom_Normalize_AxisY, OnUpdateButton)
ON_UPDATE_COMMAND_UI(IDC_Bottom_Adjust_Y, OnUpdateButton)
ON_UPDATE_COMMAND_UI(IDC_Up_Adjust_Y, OnUpdateButton)
ON_MESSAGE(WM_INITDIALOG,OnInitDialog)
END_MESSAGE_MAP()
and the function
void CVBurnBar::OnUpdateButton(CCmdUI* )
{}
but theses message handler are called very often... what can I do to avoid this function to be call so often? Is there an other way to display button NOT GRAYED in a dialog bar whitout using the ON_UPDATE_COMMAND_UI.
when I do MyButton.EnableWindow(true) if the ON_UPDATE_COMMAND_UI is not define for this button it is automatically grayed after 1/10 of a second...
What I wan't is to display and grayed my button when I want...
any idea?
Remi Morin
Rmorin@Operamail.com
Remi.Morin@Lyrtech.com
|
|
|
|
|
If you want your button to stay active all the time, do not create ON_UPDATE_COMMAND_UI - just ON_COMMAND handler. MFC scans through message maps during each idle cycle, which happens very often indeed. However, you shouldn't be worried much about that - it works the same way for toolbars, for example.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
You should be using ON_UPDATE_COMMAND_UI_RANGE(IDC_Up_Normalise_AxisY, IDC_Up_Adjust_Y, OnUpdateButton) provided the command IDs use that range. This maps the button handlers to the same function(OnUpdateButton), something it looks like your trying to do. The function does nothing because you haven`t said for it to do anything! I think that in the CVBurnBar function, if you change the parameter to (CCmdUI* pCmdUI) i.e no comments, then you should have control to change the button i.e gray it out etc (using pCmdUI->thefunctionyouwant). Also make sure the afx_msg void OnUpdateButton in the header file is changed to reflect this. To stop the button being grayed out at the start all you need to do is add a message map for ON_COMMAND_RANGE(IDC_Up_Normalise_AxisY, IDC_Up_Adjust_Y, TheFunctionYouWantToCallWhenButtonIsClicked). hope this helped slightly.
AEGC
|
|
|
|
|
From MSDN: (TN031: Control Bars)
CCmdUI Support for CDialogBar
Dialog bar buttons should be updated through the ON_UPDATE_COMMAND_UI handler mechanism. At idle time, the dialog bar will call the ON_UPDATE_COMMAND_UI handler with the command ID of all the buttons that have a ID >= 0x8000 (that is, in the range of command IDs).
The ON_UPDATE_COMMAND_UI handler can call:
Enable: to enable or disable the button.
SetText: to change the text of the button.
Customization can be done through standard window manager APIs.
Best Regards...
Carlos Antollini.
Today Is Friday!!! for All!!!
|
|
|
|
|
You tried with
void CVBurnBar::OnUpdateButton(CCmdUI* )
{
CCmdUI->Enable();
}
Carlos Antollini.
|
|
|
|
|