Copy paste in CTreeView labels - c++

I have a control derived from CTreeView in MFC SDI application (containing splitter, CTreeView and CDetailsView basically). What is working for me is editing labels in nodes of tree view by processing the end of edit
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, &CNavigationView::OnTvnEndlabeledit)
I want to add copy/paste functionality with Ctrl+C and Ctrl+V. I think this deals with TVN_BEGINLABELEDIT and TVN_KEYDOWN but I can't figure out how to make this work correctly, may be some ideas or sample?
void CNavigationView::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
if (pTVDispInfo && pTVDispInfo->item.pszText)
{
}
}
When I am trying to paste text from Notepad, pTVDispInfo->item.pszText is NULL according to debugger.
I am working in Visual Studio 2013, Windows 8.

I suppose you already have an accelerator defined in you application that also uses Ctrl-V. So inside the inplace edit control you press Ctrl+V but this causes a WM_COMMAND message to be generated from the accelerator. The accelerator executes something that aborts the inplace edit job.
In such a case You need a PreTranslateMessage handler that checks if keyboard input arrives with Ctrl+C/Ctrl+V and directs this input to the edit control that is open instead of letting the frame window accelerator to handle it.
Just set a breakpoint and look into the callstack and check what is executed when the inplace edit stops.

Related

Display and use the same MFC CList control in multiple dialogs

I am coding a test application for a windows CE device. This is the first time I am programming for a handheld device. I use MFC VC++ on Visual Studio 2008. I have found that there are many restrictions in the controls and what I could do with them when running the program on a handy versus when I run a similar program on a desktop computer.
Now, the device I am currently deploying my test program to, does not have a touchscreen and has few extra keys other that the numberpad 0-9 keys. So, I have to do with a simple GUI that uses keydowns to call specific functions like add, edit, delete etc... It also forces me to use separate dialogs for each of these functions so as to avoid unnecessary mouse cursor usage.
This leads me to my current problem: The 'ADD' dialog of my test app adds some user data to a CListCtrl that is on the 'MAIN' dialog. The 'EDIT/DELETE' dialog is to allow the user to select the desired data from its own CListCtrl and press the "ENTER" key, which thereby deletes the selected data from the 'MAIN' dialog's CListCtrl. Thus, both the main dialog and the 'EDIT/DELETE' dialog have CListCtrl with the exact same data. So, instead of having to use 2 separate list controls and using loops to copy the data to and fro among them, is there a way in which i could use the exact same CListCtrl (one and only one instance of the CListCtrl exists), but display it on 2 separate dialogs? This would remove all the copying code, as well as halve the amount of data in memory.
I tried passing a pointer to the MAIN dialog's CListCtrl to the 'EDIT/DELETE' dialog in hopes that I could redraw the control there, but in vain. I could call the RedrawWindow, RedrawItems commands, but they seem to have no effect in the 'EDIT/DELETE' dialog (I think it is because the control itself is not present on the edit/delete dialog). Any other suggestions?
You could temporarily change the parent of the ListCtrl using CWnd::SetParent to the EDIT/DELETE dialog, and set the position with CWnd::SetWindowPos to where you want to have it. When the dialog gets closed, set the parent back to the MAIN dialog.

How to sync a Progress Control with a set of data which is loading in a Dialog Box in Visual C++

I'm trying to add a progress control in my dialogs, that will step upon every iteration of a loop until completion. I've never played around with progress controls before, so I'm totally clueless as to where I should start. I've added a progress control resource view into my dialog, but it just shows up as an empty progress control. I'd like to have the progress control dynamically appear/update when after pressing a button an image from somewhere stars being loaded.
I am trying to add a progress control on a dialog box in Visual c++ environment.
After adding this tool the following code added to main.cpp :
void CPanoramicsampleDlg::OnNMCustomdrawProgress1(NMHDR *pNMHDR, LRESULT *pResult){
}
I can show procedure of loading in a Text control as follow:
sprintf_s(pack1,"Data%d%%",Event);
::SetWindowText(GetDlgItem(IDC_Static)->m_hWnd,pack1);
so in this way I can see loading process as %d in a text window but I don't know how to show loading procedure by progress control and how and where to define range or even progress bar handle for this progress control so on.
finally I would like to know is there any function for progress control for example:
::EnableWindow(GetDlgItem(IDC_Progress1)->m_hWnd);
You should first add a variable for the control, by right-clicking on the progress bar in the dialog editor, and choosing Add Variable... Your dialog class will then have an instance of a CProgressCtrl class on which you can then call the members that IInspectable has mentioned in his answer. Delete the OnNMCustomdrawProgress1 handler, you don't need it.
e.g.
m_progressCtrl.EnableWindow(TRUE);
m_progressCtrl.SetRange(0, 100);
m_progressCtrl.SetPos(75);
Then whatever that eventParam1 value is that you mention, proportion it between your start and stop value, and call SetPos with it.
Update after comment:
Do the SetRange() in the OnInitDialog() function. If you don't already have an OnInitDialog you need to override it, follow the instructions in the accepted answer of this question to do it.
VS 2008, MFC: add OnInitDialog - how?
As for where you put the SetPos(): You describe that you can already track loading progress in a text control using some or other eventParam1. That sounds like a handler or callback from what ever loading you're doing, and that is where you will instead SetPos() on the progress bar instance.
The CProgressCtrl Class provides the following members that you will have to use:
CProgressCtrl::SetRange: Allows you to set lower and upper bound. These values ideally reflect your starting state and finishing condition.
CProgressCtrl::SetPos: Used to update the current position. You would update the current position where you used to output progress in your edit control.
As an alternative to calling CProgressCtrl::SetPos with an explicit position value, you can set a step increment, calling CProgressCtrl::SetStep, and update the control with a call to CProgressCtrl::StepIt. If you know the step increment ahead of time, this is an easier way to go about updating the current position.
Additional information is available at the MSDN: Using CProgressCtrl.

how to disable message box "Fail to create Empty Document " Message box in MFC SDI application

I am using VS2010 for my MFC SDI application.
In MainFrame Class in OnCreate(LPCREATESTRUCT lpCreateStruct) function I am opening one dialog box and on IDCANCLE replay from the Dialog box I want to close my application.
I am using following code for the same in onCreate Function.
CTermsConditionDlg objTNCDlg;
if(!objTNCDlg.DoModal() == IDCANCLE){
return -1;
}
Now my Question is after return Statement the application is Showing message box as shown in Image.
I want to disable this message box and close my application.
Can any one help how can I do That.
Thank You in Advance.
Why do you place this dialog so late into you initialization?
The problem is the SDI framework that relay on some initial things that are expected to run always. In this case it is always expected that the mainframe can be created. See code in CSingleDocTemplate::OpenDocumentFile
Just place this code into InitInistance before LoadFrame or ProcessShellCommand is called. In this case you can easily terminate without disturbing problems.
Another Idea is to allow the creation of the window, but simply using a PostMessage(WM_CLOSE); In this case the initialization is done, everything is created and the application terminates again.

(MFC Visual C++): How to write inside an edit control box & save to .txt?

I'm trying to create a simple program, if you can even call it that.
It has a main dialog and inside an edit box/control thing. picture
When I try to debug (I'm using MS Visual Studio 2013) I get the "I-beam" (the flashing text-thing pointer) but I can't input any text. picture
Questions: Why? How to fix?
Also, later on I want to try writing the inputted text into a txt file. I've tried searching for it, and found that you have to use the string method... Beyond that I could not understand the explanations ;(
CODE:
void Cedit2textDlg::OnEnChangeEdit1()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialogEx::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
}
program is called edit2text. This is the ONLY part about the edit box I have in my main edit2textDlg.cpp file. The .rc you can see in the first picture.
I have found a somehow similar problem that was solved using dlg.DoModal(); and creating a variable for the edit box with a value-category, but could not understand how and why I should use it.

Adding accelerators(shortcuts) in MFC - HOW?

I found this link: http://support.microsoft.com/kb/222829
But I can't understand that much.
Ok, I understood I need to add this to my header file:
HACCEL m_hAccelTable;
and then this:
m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
to my main .cpp
But where does this go?
BOOL CAboutDlg::PreTranslateMessage(MSG* pMsg) {
if (m_hAccelTable) {
if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg)) {
return(TRUE);
}
}
return CDialog::PreTranslateMessage(pMsg);
}
I need around 6 shortcuts (CTRL + U to load something, CTRL + O to load smth else), I can't understand how this works, need a little bit of help
Now, MSDN article is misleading. It shows how to add accelerators to About box and only About box will be able to handle accelerator that is in this case equivalent of pressing the button with IDC_BUTTON1 ID.
You need to do something very different allowing all objects in your application to get a chance to handle this message. This is done for you in MDI/SDI apps.
Once you create accelerator table in the resource, you have to add accelerators: Key combination paired Accelerator key combination, when used generates command message with appropriate ID. Once you are done adding, you have to create command message handlers for each of the ID.
When accelerator is used the handler is invoked and you can add the code you need.
Now do this:
Declare HACCEL type variable to your app class. In the InitInstance call LoadAccelerators.
Use wizard to insert PreTranslateMessage override in your application class. Add following:
if (m_hAccelTable)
{
if (::TranslateAccelerator(*m_pMainWnd, m_hAccelTable, pMsg))
{
return(TRUE);
}
}
This will allow the main dialog to handle accelerators. Note *m_pMainWnd. It is your dialog handle (automatically casted).
Now you can add handlers for any accelerator to the dialog or to the application class. You can also route command messages to any window in your application using OnCmdMsg.
My advice for the future.
When you decide to make your app a dialog based, consider creating SDI application with CFormView derived class.
You can change frame style to not allow resizing and it will look like dialog based but. . .
You will have ability to use a toolbar a menu for free and most importantly you will have all accelerator and command routing for free.
The page you referenced describes adding an accelerator table to a dialog based applicaion.
Are you creating a dialog based application or just a normal MFC frame based application with a menu bar?
If you are doing the former then as the page you referenced suggest you need to override the PreTranslateMessage dialog box method.
If you are doing the later then you only need to call the CFrameWnd::LoadAccelTable function.