Creating a control in MFC application - mfc

How to Create a Button using CButton class inside the Client area. I have just tried but the control is not getting displayed in the client area.
Code i used to create button
void CcontrolsView::OnDraw(CDC* pDC)
{
CcontrolsDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CButton cb;
cb.Create(BS_PUSHBUTTON,CRect(20,20,100,100),this,10000);
// TODO: add draw code for native data here
}

1 Don't do it in the OnDraw() method. Add a message handler for WM_CREATE in there, and instead do it in there.
2 Don't use a stack based object to create the button. I would suggest adding a CButton member to your view class called m_Button (or whatever).
In your CcontrolsView::OnCreate() method add code like:
m_Button.Create(BS_PUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(20,20,100,100),this,10000);

You need to construct a new CButton, then add it to the dialog by setting its parent or owner (I forget which - set both!) and other properties like a sensible position, and then call ShowWindow(SW_SHOW) on it.

Related

Float (or detach) the tabbed CMDIChildWndEx window from CMDIFrameWndEx,any idea?

In visual studio,all opened editor windows are tabbed in the workspace.when you right click one,there is a "float" option in the menu.if you float a window,the window is detached from the tab and you can drag it anywhere and after all you can dock it back to the tab.
i created a test mdi project,it's not a default behavior.
i overrided the ID_FILE_NEW command and followed the OpenDocumentFile routine,never found out where the framework add the newly created child frame window to the tab.
in the OpenDocumentFile routine,i bumped into a CMFCTabCtrl class and there is a AddTab function.
now the AddTab function:
virtual void AddTab(
CWnd* pTabWnd,
LPCTSTR lpszTabLabel,
UINT uiImageId = (UINT)-1,,
BOOL bDetachable = TRUE
);
virtual void AddTab(
CWnd* pTabWnd,
UINT uiResTabLabel,
UINT uiImageId = (UINT)-1,
BOOL bDetachable = TRUE
);
the Remarks:
If pTabWnd points to an object that is not derived from the CDockablePane Class and
if bDetachable is TRUE, the framework automatically creates a wrapper for the pTabWnd object.
The wrapper makes the pTabWnd object detachable.
By default, the wrapper is an instance of the CDockablePaneAdapter Class.
If the functionality offered by the default wrapper is unacceptable,
use the CMFCBaseTabCtrl::SetDockingBarWrapperRTC method to specify a different wrapper.
still no luck.
i did try to on the fly create a CView and attach it to the CDocument and put that CView in a CDockablePane.so i could switch the old tabbed one to the new dockable one. it's not working yet.
So any thoughts about floating the tabbed CMDIChildWndEx window from CMDIFrameWndEx?

MFC: How to custom draw a dynamically created CListCtrl

I need to customize the head/row height of a CListCtrl. After some googling, I know that I need to subclass CListCtrl, so I wrote my own list class, with the outline as follows:
class CListCtrlCl : public CListCtrl
{
DECLARE_DYNAMIC(CListCtrlCl)
public:
...
BEGIN_MESSAGE_MAP(CListCtrlCl, CListCtrl)
ON_WM_MEASUREITEM()
ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()
void CListCtrlCl::PreSubclassWindow()
{
ModifyStyle(0,LVS_OWNERDRAWFIXED);
CListCtrl::PreSubclassWindow();
CHeaderCtrl *pHeader = GetHeaderCtrl();
m_Header.SubclassWindow(pHeader->GetSafeHwnd());
}
void CListCtrlCl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if (m_nRowHeight>0)
{
lpMeasureItemStruct->itemHeight = 100;
}
}
The problem is that this method worked if I drag a CListCtrl control in dialog template, but if I create this listctrl dynamically, like:
BOOL CListCtrlTestDlg::OnInitDialog()
{
CRect rect(7,7,300,300);
this->m_ListCtrl.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|LVS_REPORT|LVS_ALIGNLEFT|WS_BORDER | WS_TABSTOP, rect, this,IDC_LIST1 + 1);
SetWindowLong(m_ListCtrl.m_hWnd ,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES);
::SendMessage(m_ListCtrl.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
...
Then the customization code just doesn't take effect. Whatever I did, the result listctrl is the standard one without any customization. But I need to create this listctrl dynamically, so could anyone tell me what I need to do to make dynamically created clistctrl customizable?
Thanks.
You've left off the necessary style for custom drawing when you create the control. Add LVS_OWNERDRAWFIXED. That should fix your problem.
The reason is that, PreSubclassWindow is only called when you subclass a control. When you createthe control you have also control over the style.
Simply overwrite the virtual Create function and just add the style like you are doing it in the PreSubclassWindow function. Than call the base class. You can also overwrite PreCreateWindow.
But much simpler than using the ownerdraw feature is cusum draw.

Parent Window is NULL in CFormView (MFC)

I have a CFormView-derived class that has a button I am trying to call ShowWindow on. However, this call fails because the m_hWnd variable is null. Why is m_hWnd null? The dialog has the child style set in the properties window, and I'm associating the parent CFrameWnd with the form view. This view is intended to be modeless.
Code that creates view:
void CMainFrame::SwitchEditView(CRuntimeClass * pViewClass)
{
context.m_pNewViewClass=pViewClass;
context.m_pCurrentDoc=pDoc;
context.m_pNewDocTemplate=NULL;
context.m_pLastView=NULL;
context.m_pCurrentFrame=this;
m_subSplitter.CreateView(0,1,pViewClass,CSize(0,0), &context); // create new view and add it to the splitter window
}
The constructor for my CFormView-derived class:
CDFAManEditViewProject::CDFAManEditViewProject()
: CFormView(CDFAManEditViewProject::IDD)
{
// c_btnEdit is a CButton MFC control
c_btnEdit.ShowWindow(SW_SHOW); // this call fails on ASSERT(::IsWindow(m_hWnd) )
}
You are trying to access an edit control from the view constructor. But the view window has not been created yet when the constructor runs. That is why you have no m_hWnd and no edit control yet.
Move your initialization of controls into the view's OnInitialUpdate.

CMFCButton::SetToolTip(str) not work in OnInitDialog() and

I want my CMFCButton to show tooltip when mouse over.
It doesn't work if I use SetToolTip() method in OnInitDialog
CMFCButton* bt = ((CMFCButton*)GetDlgItem(IDC_MFCBUTTON1));
bt->SetTooltip(_T("tooltip"));
BUT it does work if I put this code in message handle function like another button's click handle.
What I want is that the CMFCButton could show tooltip when the dialog is created, where should I put these code?
========================
By the way, The tooltip text I set in the Property view does not work for most time.
I just derived a class
class CMyButton : public CMFCButton
{
public:
void SetDelayFullTextTooltipSet(bool DelayFullTextTooltipSet)
{
m_bDelayFullTextTooltipSet = DelayFullTextTooltipSet;
}
};
Instead of a CMFCButton variable on the Dialog class I use the button, I now have a CMyButton.
And in the OnInitDialog, after the SetTooltip call, I do
button.SetDelayFullTextTooltipSet(FALSE);
Have you called the base class' OnInitDialog()? The main point is that the control needs to be created before you call SetToolTip() on it. Step into OnInitDialog() with the debugger and see if m_hWnd of the control has a value at the moment you call SetToolTip().

is there a function in dlg class as getdocument()?

I want to get a doc* in dlg class, and i know in view class we can get doc* like
doc* pdc=getdocument();
But how can i do it in dlg class?
There is no function in CDialog to retrieve a document pointer. To give your dialog access to the document, you can add a pointer or reference to the document as a member variable of the dialog class, and initialise it in the dialog's constructor.
CMyDocument* doc = GetDocument();
CMyDialog dialog(doc);
dialog.DoModal();
MFC's CDialog class does not have built-in CDocument's. You can implement a CFormView that is derived from CView (which are part of the Document/View architecture of MFC), but CFormView is not a dialog. However, CFormView's can hold controls like a dialog - you can actually assign a dialog template to a CFormView.
you can get document from dialog by doing as follows:
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CMyProjDoc* pDoc = (CMyProjDoc*)(pFrame->GetActiveDocument());
pDoc->m_item[i].name // use