|
|
Hi Daniel,
I don't have a sample app, but can email you a code fragment if you like. I'll need your email address.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Here's the fragment I emailed you - hotmail mail has recently been bouncing and I wasn't sure if you'd get my reply.
CDlgHolding represents a tabbed dialog that can display 3 types of holdings (stock, cash and margin debt). Each type is represented by a modeless dialog. CDlgHolding contains a tab control, creates the modeless dialogs, and shows the appropriate one based on the user's selection. Here's a screenshot[^].
BEGIN_MESSAGE_MAP(CDlgHolding, CDialog)
ON_NOTIFY(TCN_SELCHANGE, TAB_CTRL, OnTabSelected)
END_MESSAGE_MAP()
BOOL CDlgHolding::OnInitDialog()
{
CDialog::OnInitDialog();
CTabCtrl* pTabCtrl = (CTabCtrl *) GetDlgItem (TAB_CTRL);
ASSERT (pTabCtrl != NULL);
pTabCtrl->InsertItem (0, " Stock Holding ");
pTabCtrl->InsertItem (1, " Cash Holding ");
pTabCtrl->InsertItem (2, " Margin Debt ");
VERIFY (m_dlgStockHolding.Create (IDD_STOCK_HOLDING, this));
VERIFY (m_dlgCashHolding.Create (IDD_CASH_HOLDING, this));
VERIFY (m_dlgMarginHolding.Create (IDD_MARGIN_HOLDING, this));
updateTabSelection();
m_dlgStockHolding.SetFocus();
return FALSE;
}
void CDlgHolding::OnTabSelected
(NMHDR* pNMHDR, LRESULT* pResult)
{
CTabCtrl* pTabCtrl = (CTabCtrl *) GetDlgItem (TAB_CTRL);
ASSERT (pTabCtrl != NULL);
long nCurrentTab = pTabCtrl->GetCurSel();
m_dlgStockHolding.ShowWindow (SW_HIDE);
m_dlgCashHolding.ShowWindow (SW_HIDE);
m_dlgMarginHolding.ShowWindow (SW_HIDE);
CWnd* pWndCurrentTab = NULL;
switch (nCurrentTab) {
case 0:
pWndCurrentTab = &m_dlgStockHolding;
break;
case 1:
pWndCurrentTab = &m_dlgCashHolding;
break;
case 2:
pWndCurrentTab = &m_dlgMarginHolding;
break;
default:
ASSERT (FALSE);
break;
}
if (pWndCurrentTab != NULL) {
CRect rectCtrl;
GetDlgItem (FRAME_TAB_DIALOG)->GetWindowRect (&rectCtrl);
ScreenToClient (&rectCtrl);
pWndCurrentTab->MoveWindow (&rectCtrl, TRUE);
pWndCurrentTab->ShowWindow (SW_SHOW);
pWndCurrentTab->Invalidate();
pWndCurrentTab->UpdateWindow();
pWndCurrentTab->BringWindowToTop();
pWndCurrentTab->SetFocus();
}
*pResult = 0;
}
Hope this helps!
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Thanks for the example Ravi it helped out quite a bit. I just have two questions, in the statement:
GetDlgItem (FRAME_TAB_DIALOG)->GetWindowRect (&rectCtrl) what is FRAME_TAB_DIALOG ? Also I noticed that your always simply getting a pointer to the tab control instead of having a member variable for it, is getting a pointer better than using a member variable?
Thanks again.
- monrobot13
|
|
|
|
|
FRAME_TAB_DIALOG is just a static frame control I use to position the modeless dialogs. Because the control's visible style is "false", it doesn't interfere with the display but yet gives me a good idea of where the modeless dialogs will appear when I'm in the resource editor.
monrobot13 wrote:
is getting a pointer better than using a member variable?
No - actually what I'm doing is slightly more inefficient. Imho, it's better to relate a member variable (of class CTabCtrl ) with the tab control rather than calling GetDlgItem() and doing the cast. It's just a habit. A bad one.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Thanks again Ravi, your help has been very much appreciated.
- monrobot13
|
|
|
|
|
Glad to be of help!
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Hey Again,
I've finally tried implementing your CTabCtrl example and I'm having some trouble with it. I've implemented the code that you sent me but it still isn't working. The dialog with the tab control will load up and show the tab that I inserted, but it wont show the dialog that's supposed to be on the tab. Here's my OnInitDialog function:
BOOL CDataManDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_tabData.InsertItem (0, " Media Sales ");
m_tabData.InsertItem (1, " Temp Garbage ");
VERIFY (m_dlgSales.Create (IDD_MEDIASALES_DIALOG, this));
m_dlgSales.SetFocus ();
return FALSE;
} I added a bogus tab so that I could test the TCN_SELCHANGE handler and when I click onto the first tab it creates the dialog but it's not inside the tab control, it's way off to the side. Here's my TCN_SELCHANGE handler:
void CDataManDlg::OnTabSelected(NMHDR* pNMHDR, LRESULT* pResult)
{
int nCurrentTab = m_tabData.GetCurSel ();
m_dlgSales.ShowWindow (SW_HIDE);
CWnd* pWndCurrentTab = NULL;
switch (nCurrentTab) {
case 0:
pWndCurrentTab = &m_dlgSales;
break;
case 1:
break;
default:
ASSERT (FALSE);
break;
}
if (pWndCurrentTab != NULL) {
CRect rectCtrl;
GetDlgItem (FRAME_TAB_DIALOG)->GetWindowRect (&rectCtrl);
ScreenToClient (&rectCtrl);
pWndCurrentTab->MoveWindow (&rectCtrl, TRUE);
pWndCurrentTab->ShowWindow (SW_SHOW);
pWndCurrentTab->Invalidate ();
pWndCurrentTab->UpdateWindow ();
pWndCurrentTab->BringWindowToTop ();
pWndCurrentTab->SetFocus ();
}
*pResult = 0;
} I'm just wondering if you could tell what I'm doing wrong here, and would it be possible for you to send me a complete VC6 project?
Thanks again for the help it's been very much appreciated.
-monrobot13
|
|
|
|
|
Man, sorry for so many posting but I'm really trying to get this working. I got the TCN_SELCHANGE handler to work by changing the style of the dialog (that should be in the CTabCtrl ) to child and it's border to none (maybe I'm an idiot for not doing that in the first place) but the dialog still wont show on the initialization. Again any help would be much appreciated.
- monrobot13
|
|
|
|
|
changing the style of the dialog (that should be in the CTabCtrl) to child and it's border to none
Sorry, I should've mentioned that!
the dialog still wont show on the initialization.
The dialog should only show up when the tab selection message is handled.
when I click onto the first tab it creates the dialog but it's not inside the tab control, it's way off to the side.
If it's showing up at a bad location, check the location of the FRAME_TAB_DIALOG static control.
Sorry, but I can't send you a sample VC++ project because I snipped the code I sent you from a much larger codebase.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
I think I got it all working now
Thanks a lot for you help Ravi I don't think I could have got it working without it.
Cheers!
- monrobot13
|
|
|
|
|
Glad to be of help! I just pointed you in the right direction - you did all the work!
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Thanks for the code...
One question: Why do you call all this member functions?
pWndCurrentTab->MoveWindow (&rectCtrl, TRUE);
pWndCurrentTab->ShowWindow (SW_SHOW);
pWndCurrentTab->Invalidate();
pWndCurrentTab->UpdateWindow();
pWndCurrentTab->BringWindowToTop();
pWndCurrentTab->SetFocus();
It is not enough to call the MoveWindow and the ShowWindow function?
Why do you call Invalidate and UpdateWindow ? Does the system not automaticly paint the window after ShowWindow ?
Does I need to call BringWindowToTop ? And why?
--
Nice greets, Daniel.
|
|
|
|
|
Hi Daniel,
I call Invalidate() and UpdateWindow() to force an immediate repaint. The latter is necessary as a workaround for the painting bug in static controls.
I call SetFocus() to ensure that focus is transferred to the first control in the modeless dialog, which is what the user would expect.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
And why do you call BringWindowToTop ? Does it not automatic drawn on the top?
--
Nice greets, Daniel.
|
|
|
|
|
I do that to ensure it's above the tab control at all times. When the user clicks on the tab control, the modeless dialog's Z order changes. BringWindowToTop() makes it topmost again.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
Hi,everyone:
I want to print a picture drawn in one of my windows.
The picture's base class is a CChart named m_chart.
The print programme is as following:
CWnd *pWnd = &m_chart;
CWindowDC dcWnd(pWnd);
CDC memDC;
CRect rect;
HBITMAP bmp;
CBitmap bitmap0;
memDC.CreateCompatibleDC(&dcWnd);
pWnd->GetWindowRect(rect);
bitmap0.CreateCompatibleBitmap(&dcWnd, rect.Width(),rect.Height() );
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap0);
CPrintDialog dlg(FALSE);
if (dlg.DoModal() ==IDOK)
{
// Create a CDC object for the device context we got
CDC dcPrinter;
dcPrinter.Attach(dlg.m_pd.hDC);
// Determine width, height and orientation
LPDEVMODE pDM = dlg.GetDevMode();
int dmOrientation = pDM->dmOrientation;
int Width = dcPrinter.GetDeviceCaps(HORZRES) - 100;
int Height = dcPrinter.GetDeviceCaps(VERTRES) - 100;
// Describe print job to print spooler
DOCINFO docInfo;
docInfo.cbSize = sizeof(docInfo);
docInfo.fwType = 0;
docInfo.lpszDocName = "Print Thermal Schedule!";
docInfo.lpszOutput = NULL;
docInfo.lpszDatatype = NULL;
// Start a document
if (0 < dcPrinter.StartDoc(&docInfo))
{
// Start a page; you might call StartPage/EndPage more than once;
// you'll have one call pair for each page you print.
if (0 < dcPrinter.StartPage())
{
// measure the printable page
int nOffsetX = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX);
int nOffsetY = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY);
int nHorzRes = dcPrinter.GetDeviceCaps(HORZRES);
int nVertRes = dcPrinter.GetDeviceCaps(VERTRES);
// load bitmap from file
bmp = NULL;
//bmp = (HBITMAP)bitmap0.GetSafeHandle();
//bmp = (HBITMAP) bitmap0;
HDC hdc;
bmp = (HBITMAP) dcWnd.GetCurrentBitmap()->m_hObject;
dcWnd.SelectGdiObject(hdc,bmp);
CBitmap bitmap;
bitmap.Attach (bmp);
// copy bitmap into memory DC
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dcPrinter);
CBitmap* pOldBitmap = dcMemory.SelectObject(&bitmap);
BITMAP bm;
bitmap.GetBitmap(&bm);
// determine magnification
double Magnification;
double MagnificationW = (double)Width / (double)bm.bmWidth;
double MagnificationH = (double)Height / (double)bm.bmHeight;
Magnification = MagnificationW >= MagnificationH ? MagnificationH :
MagnificationW;
int iBitMap_X = (int)((double)bm.bmWidth * Magnification);
int iBitMap_Y = (int)((double)bm.bmHeight * Magnification);
int iOffset_X = (dcPrinter.GetDeviceCaps(HORZRES) - iBitMap_X - 50) / 2;
int iOffset_Y;
if (dmOrientation == 1) iOffset_Y = 50;
else iOffset_Y = (dcPrinter.GetDeviceCaps(VERTRES) - iBitMap_Y) / 2;
// stretch memory DC into printer DC
dcPrinter.StretchBlt(iOffset_X, iOffset_Y, iBitMap_X,
iBitMap_Y,&dcMemory,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);//dcMemory
dcMemory.SelectObject(pOldBitmap);
// close the page
dcPrinter.EndPage();
}
else
{
MessageBox("Couldn't start new page!");
}
// close the document. Printing actually starts now!
dcPrinter.EndDoc();
}
else
{
MessageBox("Couldn't start document.");
}
}
else
{
MessageBox("You have no default printer. You must set a default printer before priting.");
}
When I degugged,I can see the value of bmp and the length of iBitMap_X and so so.
I likes that I have got the handle to the bmp.
But I print nothing out.
Can you tell me why?
thanks a lot.
wang
|
|
|
|
|
what's the return value of the StretchBlt call?
All you have to do is tell the people they are being attacked, and denounce the opposition for lack of patriotism and exposing the country to danger.
-- Herman Goering, on how to control the public
|
|
|
|
|
Hi.
Do delete STL functions such as remove() and erase() calls a class destructor if the element is a pointer to an object? For example, consider a vector of pointers to ClassX objects and a list of pointers to ClassX objects..
[code]
std::vector<classx *=""> sTextVec;
ClassX *pCX;
sTextVec.push_back(pCX);
...
// Now you need to deallocate memory from pText.
// Do functions such as remove() and erase() call ClassX
// destructor, or do you have to delete them explicitly?
[/code]
Thanks,
Kuphryn
|
|
|
|
|
kuphryn wrote:
Do functions such as remove() and erase() call ClassX
destructor, or do you have to delete them explicitly?
the container calls the destructor of the contained type. in your case, the contained type is a pointer, so it has no destructor (it's just a number). even more importantly, the destructor for a pointer does not delete the pointed-to object. this is nice, because you can use pointers as container elements and you don't have to worry that the objects that they point to will be deleted.
so, to really answer your question: yes, you have to manually delete the objects when you're done with them.
-c
All you have to do is tell the people they are being attacked, and denounce the opposition for lack of patriotism and exposing the country to danger.
-- Herman Goering, on how to control the public
|
|
|
|
|
typical vector clean up code goes 'something like:'
for ( vector_iter = vector.begin();
vector_iter != vector.end();
vector_iter++ )
{
delete (*vector_iter);
}
vector.clear();
Just trying to keep the forces of entropy at bay
|
|
|
|
|
Okay. Thanks everyone.
Kuphryn
|
|
|
|
|
Hi, I am writing a Activex control in VC++(ATL,MFC). In this dll, I also have designed some classes used to support the functionality of this ActiveX Control. There are many places I need to use string, both in the classes and the ATL object's interface. But I don't know which string type to use. Could anyone give me a guidline on how to choose the following string types?
string
wstring
BSTR
_bstr_t
CComBSTR
Thanks!
Sherry
|
|
|
|
|
use BSTR on the external interfaces and choose between _bstr_t and CComBSTR for your internal string handling. they each have their benefits, though neither is as powerful as CString.
-c
All you have to do is tell the people they are being attacked, and denounce the opposition for lack of patriotism and exposing the country to danger.
-- Herman Goering, on how to control the public
|
|
|
|
|
Thank you Chris!
Then how abour string and wstring? I found string and wstring are widely used in the project I am currently working on, I don't know why they pick them instead of _bstr_t and CComBSTR.
|
|
|
|