Class derived from CEdit does not take any numeric value - mfc

I am new to MFC. I created Edit Box dynamically by generating my own CEdit class which is CMYEditEx it has created the edit box on dialog but it does not take any numeric value. I want to make edit box only for numeric value.
i am not able to write any things in edit box but my purpose is to create edit box which only take numeric values . this function is implemented in OnItDlg
CMYEditEx* pEdit = new CMYEditEx;
pEdit->Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_NUMBER ,
CRect(130, aSize, 260, bSize), this, 1);
BOOL CMYEditEx::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
int nTextLength = this->GetWindowTextLength();
if (pMsg->message == WM_CHAR)
{
// Ignoring 0 to 9
if ((pMsg->wParam >= '0' && pMsg->wParam <= '9'))
{
return true;
}
}
return CEdit::PreTranslateMessage(pMsg);
}

Related

unable to set focus to CEdit control

I encounter a problem with CEdit textbox , the exact problem is that i unable to Set Focus to the control after creating it.
What i want to do is:
Create CEdit control temporary.
Set focus to the control.
Get the number from the control and store it in a value.
Destroy control after 10 second.
After some research on internet i couldn’t find solution to the problem , therefore i address to you.
Hope to find a solution. Thanks in advance.
i tried
editctrl.SetFocus();
DWORD dw = LOWORD(editctrl.GetDlgCtrlID()) | HIWORD(EN_SETFOCUS);
SendMessage(WM_COMMAND,(WPARAM)dw, (LPARAM)editctrl.GetHandle());
BOOL CViewsDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == 0xBB /*+*/)
{
if (!editctrl)
{
editctrl.Create(ES_NUMBER | WS_CHILD|WS_VISIBLE | WS_BORDER | WS_TABSTOP, CRect(0, 0, 100, 20), this, NULL);
editctrl.ShowWindow(SW_SHOW);
editctrl.SetFocus();
//DWORD dw = LOWORD(editctrl.GetDlgCtrlID()) | HIWORD(EN_SETFOCUS);
//SendMessage(WM_COMMAND,(WPARAM)dw, (LPARAM)editctrl.GetHandle());
telestis = e_sinplin;
SetTimer(1, 10000, NULL);
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
You need to use CDialog::GotoDlgCtrl to set focus in dialog windows.

How to adjust the size of a CDockablePane?

I am writing a SDI application on Visual Studio 2012. The MFC Wizard generated two CDockablePane-derived objects. The right-side CPropertiesWnd (CDockablePane-derived) object is named m_wndProperties. I embed in m_wndProperties a CPropertySheet object with a CPageNone (CPropertyPage-derived) object captioned "HELP" like this (I use the CPropertySheet class directly). However, the real size of the CPropertySheet object is bigger.
I have tried to adjust the size of the dialog related to the CPageNone object (named m_pageNone) in the Dialog Editor. This has no effect. In the MainFrm.cpp, the only lines relating to m_wndProperties I can find are:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
.....
m_wndProperties.EnableDocking(CBRS_ALIGN_RIGHT);
DockPane(&m_wndProperties);
.....
}
.....
BOOL CMainFrame::CreateDockingWindows()
{
.....
CString strPropertiesWnd;
bNameValid = strPropertiesWnd.LoadString(IDS_PROPERTIES_WND);
ASSERT(bNameValid);
if (!m_wndProperties.Create(strPropertiesWnd, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PROPERTIESWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
{
TRACE0("無法建立 [屬性] 視窗\n");
return FALSE; // 無法建立
}
.....
}
.....
void CMainFrame::SetDockingWindowIcons(BOOL bHiColorIcons)
{
.....
HICON hPropertiesBarIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_PROPERTIES_WND_HC : IDI_PROPERTIES_WND), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
m_wndProperties.SetIcon(hPropertiesBarIcon, FALSE);
}
And here is the AdjustLayout() in my PropertiesWnd.cpp:
void CPropertiesWnd::AdjustLayout()
{
if (GetSafeHwnd () == NULL || (AfxGetMainWnd() != NULL && AfxGetMainWnd()->IsIconic()))
{
return;
}
CRect rectClient;
GetClientRect(rectClient);
m_PropertySheet.SetWindowPos (NULL, rectClient.left, rectClient.top, rectClient.Width (), rectClient.Height (), SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
}
And in my PageNone.cpp, I only have three functions: the default constructor, the default destructor and DoDataExchange.
My question is how can I adjust the size of m_wndProperties or m_pageNone to fit each other? Thank you very much.
I have got this working in a different way (the code is too large to give in this answer, but the main points are:
a) don't do anything in CMainFrame::OnCreate()
b) in CMainFrame::CreateDockingWindows(), after m_wndProperties.Create(), add the following code
m_PropertySheet.Create(...);
CRect rc;
m_PropertySheet.GetRect(&rc);
m_wndProperties.SetMinSize(rc.Width(), rc,Height());
m_wndProperties.EnableDocking(CBRS_ALIGN_RIGHT);
DockPane(&m_wndProperties);
ShowPane(&m_wndProperties, TRUE, FALSE, TRUE);
Your code in AdjustLayout() is plausible right, but I think during startup it will be called too early. Because the default size will be read from CWinAppEx::LoadState(), which always read the previous size from the Registry. It can probably disabled with CWinAppEx::EnableLoadWindowPlacement(FALSE). not tested.
Post a User-Defined Message at the end of InitInstance(). Or just try with a timer in CMainFrame::Create() .. SetTimer(123,2000,NULL);
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 123)
{
m_wndProperties.SetWindowPos(this, 0, 0, 400, 200, SWP_NOZORDER | SWP_FRAMECHANGED);
RecalcLayout();
KillTimer(123);
}
CFrameWndEx::OnTimer(nIDEvent);
}

MFC redirect/catching MESSAGE_MAP | PreTranslateMessage?

I have a problem using MESSAGE_MAP &/or PreTranslateMessage. This may be a design issue but I'm not sure. The main issue is MESSAGE_MAP code not being called & not sure how to do same via PreTranslateMessage. ie as follows:
//MyCDialogEx : public CDialogEx
class MyCDialogEx::Init()
{
CFlatSplitterWnd m_cSplitter; //http://www.codersource.net/2010/01/29/mfc-splitter-window/
m_pFrame = new CFlatFrameWnd;
m_pFrame->Create(strMyClass, L"", WS_CHILD, rect, this);
m_pFrame->ShowWindow(SW_SHOW);
m_cSplitter.CreateStatic(m_pFrame, 1, 2);
m_cSplitter.ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_NOSIZE | SWP_NOACTIVATE);
m_cSplitter.CreateView(0, 0, RUNTIME_CLASS(CHolderView), CSize(100, 100), &ccc);
CHolderView* pView = (CHolderView*)m_cSplitter.GetPane(0, 0);
ASSERT_VALID(pView);
pView->setWnd(&m_TreeCtrl);
pView->setOwner(this, IDC_TREECTRL);
const DWORD dwStyle = LBS_NOTIFY | WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES
| TVS_LINESATROOT | TVS_CHECKBOXES | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP;
m_TreeCtrl.Create(dwStyle, CRect(0, 0, 1, 1), pView, IDC_TREECTRL);
}
BEGIN_MESSAGE_MAP(MyCDialogEx, CDialogEx)
ON_NOTIFY_REFLECT(WM_ONMYCLICK, OnClickTreectrl) //this & following not called
ON_NOTIFY(NM_CLICK, IDC_TREECTRL, OnClickTreectrl)
ON_NOTIFY(TVN_ITEMCHANGED, IDC_TREECTRL, OnItemchangedTreectrl)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREECTRL, OnSelchangedTreectrl)
ON_NOTIFY(TVN_KEYDOWN, IDC_TREECTRL, OnKeydownTreectrl)
END_MESSAGE_MAP()
BOOL MyCDialogEx::PreTranslateMessage(MSG* pMsg)
{
if (GetFocus() && GetFocus()->GetDlgCtrlID() == IDC_TREECTRL)
{
//what/how goes in here to catch NM_CLICK, TVN_ITEMCHANGED etc??
if (pMsg->message == WM_LBUTTONDOWN)
{
switch (LOWORD(pMsg->wParam))
{
case NM_CLICK:
break;
}
}
if (pMsg->message == WM_KEYDOWN)
TRACE(L"WM_KEYDOWN\n");
if (pMsg->message == WM_KEYUP)
TRACE(L"WM_KEYUP\n");
}
return MyCDialogEx::PreTranslateMessage(pMsg);
}
void MyCDialogEx::OnClickTreectrl(NMHDR *pNMHDR, LRESULT *pResult) //not called
{
TRACE(L"tree click\n");
*pResult = 0;
}
MESSAGE_MAP works if I house these in CHolderView class MESSAGE_MAP, but I rather not as it's just a container class & will possibly be used elsewhere in my project.
What I'd really like to do is use MESSAGE_MAP to minimize coding via PreTranslateMessage (& if it's possible to redirect to MESSAGE_MAP, how?). If I must resort to PreTranslateMessage or other, then how do I use this so I can catch the relevant NM_CLICK, TVN_ITEMCHANGED for tree control etc.
Thank you.
EDIT: oh & the following don't help, not relevant or don't sufficiently explain:
How to get Click Event of Treeview(CTreeCtrl) in MFC created at runtime?
How to redirect MFC messages to another object?
How can identify Mouse Click event in PreTranslateMessage?
The problem is that the tree view will send all its notifications to the parent window. And the parent windows is the CHolderWindow.
Messages are not routed like WM_COMMAND messages. So handler for WM_COMMAND messages may reside anywhere in the notification path.
But regular window control notifications are always handled in the direct parent of the window. In MFC you can redirect such notfications to the child window control itself. Using ON_..._REFLECT.
A trick can be: Set a pointer to a window to the holder window, that should receive all messages. Than accept all WM_COMMAND and all WM_NOTIFY messages in the holder window and resend them to the new window.
PreTranslateMessage is another thing. The target window always receives a call first. Than all parents will get a chance until somebody in the chain of PreTranslateMessage calls returns TRUE.

Unable to change Tab's label Text of VC++ CMFCOutlookBar

Its been a while i have stopped working on VC++ and now i have some project which i have again started my development on VC++.... I am having a strange issue right now the label of the control is not getting change at all here is my code for initialization of mfcoutlookbar
BOOL CMainFrame::CreateOutlookBar(CMFCOutlookBar& bar, UINT uiID, CMFCShellTreeCtrl& tree, CCalendarBar& calendar,CListCtrlBar &listctrl,int nInitialWidth)
{
bar.SetMode2003();
BOOL bNameValid;
CString strTemp;
bNameValid = strTemp.LoadString(IDS_SHORTCUTS);
ASSERT(bNameValid);
if (!bar.Create(strTemp, this, CRect(0, 0, nInitialWidth, 32000), uiID, WS_CHILD | WS_VISIBLE | CBRS_LEFT))
{
return FALSE; // fail to create
}
CMFCOutlookBarTabCtrl* pOutlookBar = (CMFCOutlookBarTabCtrl*)bar.GetUnderlyingWindow();
if (pOutlookBar == NULL)
{
ASSERT(FALSE);
return FALSE;
}
pOutlookBar->EnableInPlaceEdit(FALSE); //we dont want editing
static UINT uiPageID = 1;
// can float, can autohide, can resize, CAN NOT CLOSE
DWORD dwStyle = AFX_CBRS_FLOAT | AFX_CBRS_AUTOHIDE | AFX_CBRS_RESIZE;
CRect rectDummy(0, 0, 0, 0);
const DWORD dwTreeStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
//Create tree
tree.Create(dwTreeStyle, rectDummy, &bar, 1200);
//bNameValid = strTemp.LoadString(IDS_FOLDERS);
ASSERT(bNameValid);
pOutlookBar->AddControl(&tree, L"Folders", 2, TRUE, dwStyle);
//create calender
calendar.Create(rectDummy, &bar, 1201);
// bNameValid = strTemp.LoadString(IDS_CALENDAR);
// ASSERT(bNameValid);
pOutlookBar->AddControl(&calendar, L"CALLLLLL",1, TRUE, dwStyle);
//create list control bar
listctrl.Create(rectDummy,&bar,1202);
// bNameValid = strTemp.LoadString(IDS_DASHBOARD);//Dashboard to check the statistics and statical reports
// ASSERT(bNameValid);
pOutlookBar->AddControl(&listctrl, L"Some", 0, TRUE, dwStyle); //the digit represent icon
bar.SetPaneStyle(bar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
pOutlookBar->SetImageList(theApp.m_bHiColorIcons ? IDB_PAGES_HC : IDB_PAGES, 24);
pOutlookBar->SetToolbarImageList(theApp.m_bHiColorIcons ? IDB_PAGES_SMALL_HC : IDB_PAGES_SMALL, 16);
pOutlookBar->RecalcLayout();
BOOL bAnimation = theApp.GetInt(_T("OutlookAnimation"), TRUE);
CMFCOutlookBarTabCtrl::EnableAnimation(bAnimation);
bar.SetButtonsFont(&afxGlobalData.fontBold);
return TRUE;
}
if you see i am using two different controls by providing them the text label e,,g,
pOutlookBar->AddControl(&listctrl, L"Some", 0, TRUE, dwStyle);
and the other is
pOutlookBar->AddControl(&calendar, L"CALLLLLL",1, TRUE, dwStyle);
now the label "Some" and "CALLLLLL" is not being displayed i have tried everything but i dont know why its still displaying the default text of
"Calenders" and "Folders"
I have changed all the text inside String table as well ...this code is generated by Visual Studio C++ by wizard using Office 2000.
What is the mistake i am doing???
Okay finally figured out the problem is the cache , the outlookbased bar for any application save the caption and label in registry...so cleaning your solution rebuilding it again and again will not give you the right tabs captions unless you delete the registry entries for that application.
HKEY_USERS\S-1-5-21-3153867254-3211561466-2840709754-1000\Software\Local AppWizard-Generated Applications\test2
and then delete this test2 project key ....after that run your application it will display the correct label.

MFC CEdit object in a CDialogEx object

I'd be very grateful if anyone could help me with this? I'm trying to create a dialog box with a text box in it for receiving error messages. I've added ON_WM_CREATE to the message map, and written this function which the debug goes through, but the object doesn't display.
int CImportDatatoAPMDlg::OnCreate(LPCREATESTRUCT LpCreateStruct)
{
if(CWnd::OnCreate(LpCreateStruct) == -1)
{
return -1;
}
CEdit *MessageBox = new CEdit;
MessageBox->Create(WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL,CRect(100, 200, 450, 150), this, 0x1552);
return 0;
}
Do I have to make a dummy box when I'm designing the dialog box. I've already done this for the rest of the controls? I'm also wondering where I give this object a number ID combination?
Thanks,
James
You normally should use VisualStudio resource editor to add controls to your dialog. If you want to do it manually then create and add controls in your overriden OnInitDialog method:
BOOL CImportDatatoAPMDlg::OnInitDialog() {
BOOL bRes = CDialog::OnInitDialog();
CEdit *MessageBox; // !!! put it into class definition
MessageBox = new CEdit
MessageBox->Create(WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL,CRect(100, 200, 450, 150), this, 0x1552);
return bRes;
}