Link to home
Start Free TrialLog in
Avatar of Peter Chan
Peter ChanFlag for Hong Kong

asked on

Problem to project

Hi,
To this thread

https://www.experts-exchange.com/questions/28700741/Adjust-Mfcapp.html?anchorAnswerId=40919152#a40919152

I do not know where I can find out "main" event within the current project, for further having in/out parameters.
Avatar of sarabande
sarabande
Flag of Luxembourg image

in mfc app the main function was moved in the framework. the first function where you could add initialization code is the InitInstance function of the application class, in your case in the CBinaryFileViewer::InitInstance function in binaryfileviewer.cpp (given that the name of your new mfc app was BinaryFileViewer).

In InitInstance the dialog object was created and DoModal function was called. between these satements you may call GetCommandLine to get the commandline parameters as a string.

CString strCmdLine = GetCommandLine();

it contains the full path to your executable + all parameters passed for arguments.

Sara
Avatar of Peter Chan

ASKER

Many thanks. How to refer to 2nd, 3rd parameters (or output parameter)?
SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Many thanks Sara.
where is "CCommandLineInfo" located at, within the current project?
CCommandLineInfo is an mfc class.

by calling ParseCommandLine which is a member function of CWinApp which is the base class of your wizard-generated application class CBinaryFileViewer, the CCommandLineInfo serves as a helper that allows you to provide a customized ParseParam function to collect the arguments. actually, the design seems to be a little bit over-sophisticated. note, for a gui program command line parameters normally were not used since you always could add input fields to the dialog form(s) what is more flexible and also allows to start the program from explorer. if you handle parameters nevertheless, you probably should suppress the gui in this case and use the mfc like you would use a console program.

Sara
Very sorry, after I've re-built the project, I still cannot find out "CCommandLineInfo".
I still cannot find out "CCommandLineInfo".
what do you mean by "cannot find out"? do you have compiler or build errors?

the following two statements compile if i put them into InitInstance function before the dlg.DoModal() call.

    CCommandLineInfo cli;
    ParseCommandLine(cli);

if you put the derived class CommandLineArguments above the InitInstance function (in binaryfileviewer.cpp) and replace 'CCommandLineInfo cli;' by 'CommandLineArguments cli;' the ParseCommandLine would use the derived class instead of the mfc class.

you then would get the CommandLineArguments::ParseParam get called for each argument. note, if you start the mfc exe in the visual studio by f5, you also could pass arguments via menu
    project - properties - configuration properties - debugging - command arguments

be aware that you have two configurations for debug and release.

Sara
Many many thanks Sara.

where should I put these?
CString strCmdLine = GetCommandLine();
strCmdLine += _T(' ');  // add a space for easier parsing
int pos1 = 0;
struct KeyValue
{
     CString strKey;
     CString strValue;
};
std::vector<KeyValue> args;
while ((pos1 = strCmdLine.Find(_T('='), pos1)) > 0)
{
      int pos2 = strCmdLine.ReverseFind(_T('_'), pos1);
      int pos3 = strCmdLine.Find(_T('_'), pos1);
      if (pos2 < 0 || pos3 < 0) break;
      KeyValue kv;
      kv.strKey = strCmdLine.Mid(pos2+1, pos1-pos2+1);
      kv.strVal = strCmdLine.Mid(pos1+1, pos3-pos1+1);
      args.push_back(kv);
      pos1 = pos3;     
}

Open in new window

nowhere. this was alternative code to ParseCommandLine with derived class CommandLineArguments.

Sara
what are the arguments you want to pass to the program?

Sara
Hi Sara,
I want to pass one name, and one value, while the name exists among the files.
I apply part (b) codes to the project and got these

Error	1	error C2039: 'vector' : is not a member of 'std'	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	44	1	BinaryFileViewer
Error	2	error C2143: syntax error : missing ';' before '<'	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	44	1	BinaryFileViewer
Error	3	error C4430: missing type specifier - int assumed. Note: C++ does not support default-int	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	44	1	BinaryFileViewer
Error	4	error C2238: unexpected token(s) preceding ';'	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	44	1	BinaryFileViewer
Error	5	error C2039: 'strVal' : is not a member of 'KeyValue'	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	53	1	BinaryFileViewer
Error	6	error C2065: 'args' : undeclared identifier	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	54	1	BinaryFileViewer
Error	7	error C2228: left of '.push_back' must have class/struct/union	c:\binaryfileviewer\binaryfileviewer\binaryfileviewer.cpp	54	1	BinaryFileViewer

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
#include <vector> is missing. the errors with 'args' are following errors.

either change strValue to strVal in struct KeyValue or change  kv.strVal to kv.strValue

(some errors are only typos or missing includes which you have seen and solved with my help multiple times. you really should be able to solve simple errors yourself).

Sara
Good day Sara,
1st para is one name
2nd para is the relevant value to be input (replace previous) for relevant name
3rd para means "Updated" or not (0 for done; 1 for not)
if 3rd parameter is supposed to be output you need another way since commandline parameters are input only.

for 1st and 2nd i would suggest to pass them as key=value pairs. then the order is arbitrary and you may enhance the functionality or use an ini file instead with little changes. finally i would add a parameter which tells what  to do. all together would lead to a call like

binaryfileviewer do=updnam old=hkhkhkjhkjhjkh new=tutituiututtik

in ParseParam function, you easily could parse each of the pairs and pass it to m_pDlg where we could do further action.

Sara

and add a constructor

     CommandLineArguments(CBinaryFileViewerDlg * pDlg) : m_pDlg(pDlg) {}

to the public part of the class.

where is the public part?



then in ParseParam  you can check whether the argument kv.strKey == "name" and if yes,

    m_pDlg->m_strNameKey = kv.strVal;

to set the value to the dialog.

can I have more details to this?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

 in the constructor initialize it with value eNoAction.
 

 Is it fine I have this
 
 EActionCode m_eCmdLineAction=eNoAction;

Open in new window


within Dialog header file?

I think this struct below

struct CommandLineArguments : public CCommandLineInfo
{
private:
	CBinaryFileViewerDlg * m_pDlg;
	std::vector<KeyValue> args;
public:
	virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast)
	{
		CString strParam = pszParam;
		int pos = strParam.Find(_T(' '));
		if (pos > 0)
		{
			KeyValue kv;
			kv.strKey = strParam.Left(pos);
			kv.strValue = strParam.Mid(pos + 1);
			if (kv.strKey.CompareNoCase("old") == 0)
			{
				m_pDlg->m_strNameKey = kv.strKey;
			}
		}
		else if (kv.strKey.CompareNoCase("do") == 0)
		{
			if (kv.strVal.CompareNoCase("updnam") == 0)
			{
				m_pDlg->m_eCmdLineAction = eUpdNam;
			}
		}
	}
};

Open in new window


is having problem, right?
EActionCode m_eCmdLineAction=eNoAction;
no. members were initialized in the constructor, not in the class definition.

the constructor (function) can be found in cpp file of dialog class by searching for CBinaryFileViewerDlg::CBinaryFileViewerDlg

here you have two possibilties to init class members:

(1) add it to the initializer list with is between : and {

CBinaryFileViewerDlg::CBinaryFileViewerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBinaryFileViewerDlg::IDD, pParent)
        , m_eCmdLineAction(eNoAction)
{

Open in new window


or , alternatively

(2) put an assignment into the constructor body:

CBinaryFileViewerDlg::CBinaryFileViewerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBinaryFileViewerDlg::IDD, pParent)
{
         ...
         m_eCmdLineAction = eNoAction;

Open in new window


I think this struct below ... is having problem, right?
not only the struct but the whole code since you didn't apply any of my corrections given above ...

Sara

in ParseParam you then have

   
else if (kv.strKey.CompareNoCase("do") == 0)
   {
          if (kv.strVal.CompareNoCase("updnam") == 0)
          {
                 m_pDlg->m_eCmdLineAction = eUpdNam;
          }

Many thanks Sara.

Can I know what is missing to ParseParam to my codes?
as told the structure KeyValue and vector args could be omitted if you pass the parameters immediately to the dialog.

struct CommandLineArguments : public CCommandLineInfo
{
private:
	CBinaryFileViewerDlg * m_pDlg;
	//std::vector<KeyValue> args;
public:
       CommandLineArguments(CBinaryFileViewerDlg * pDlg) : m_pDlg(pDlg) {}
       virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast)
       {
		CString strParam = pszParam;
		int pos = strParam.Find(_T('='));
 		if (pos > 0)
		{
		        CString strKey = strParam.Left(pos);
			CString strVal = strParam.Mid(pos + 1);
			if (strKey.CompareNoCase("old") == 0)
			{
				m_pDlg->m_strNameKey = strKey;
			}
                        else if (strKey.CompareNoCase("new") == 0)
			{
                                // Did you create the new member and the new edit control???
				m_pDlg->m_strNewName = strKey;
			} 
   		        else if (strKey.CompareNoCase("do") == 0)
		        {
			      if (strVal.CompareNoCase("updnam") == 0)
			      {
				   m_pDlg->m_eCmdLineAction = eUpdNam;
			      }
                        }
		}
	}
};

Open in new window

Many thanks Sara.

I've applied the codes to the project. Any advice to this?
 
Error	1	error C2614: 'CBinaryFileViewerDlg' : illegal member initialization: 'm_eCmdLineAction' is not a base or member	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewerdlg.cpp	68	1	BinaryFileViewer
Error	2	error C2664: 'int ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CompareNoCase(const wchar_t *) const' : cannot convert argument 1 from 'const char [4]' to 'const wchar_t *'	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewer.cpp	58	1	BinaryFileViewer
Error	3	error C2664: 'int ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CompareNoCase(const wchar_t *) const' : cannot convert argument 1 from 'const char [4]' to 'const wchar_t *'	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewer.cpp	62	1	BinaryFileViewer
Error	4	error C2039: 'm_strNewName' : is not a member of 'CBinaryFileViewerDlg'	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewer.cpp	65	1	BinaryFileViewer
Error	5	error C2664: 'int ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CompareNoCase(const wchar_t *) const' : cannot convert argument 1 from 'const char [3]' to 'const wchar_t *'	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewer.cpp	67	1	BinaryFileViewer

Open in new window

'm_eCmdLineAction' is not a base or member
you forgot to add the (public) member to the dialog class. the enum should be also added to the dialog header above class definition.

cannot convert argument 1 from 'const char [4]' to 'const wchar_t *
all string arguments to CString member functions need to be wide characters. so change "old" and "new" and "do" and "updnam" to _T("old"), _T("new"), _T("do"), _T("updnam").

Sara
Do you mean I should change these
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	// Implementation
protected:
	DECLARE_MESSAGE_MAP()

Open in new window


to public?

where are the four arguments declared, which I should further change?
which 'four' arguments?

if the CBinaryFileViewerDlg is an exact copy of CMfcApplication9Dlg beside of the name, you have for each edit control in the dialog form a CString member variable defined. for example in the form there is a edit control

Name Key : [_________________]

with IDC_EDIT_NAMEKEY  as the resource id.

if you look into cpp file for IDC_EDIT_NAMEKEY you'll see two entries in (wizard-generated) DoDataExchange function:

    DDX_Control(pDX, IDC_EDIT_NAMEKEY, m_editNameKey);
    DDX_Text(pDX, IDC_EDIT_NAMEKEY, m_strNameKey);

the first provides a member control 'm_editNameKey' of type CEdit. the second provides a CString member 'm_strNameKey'.

if 'UpdateData(FALSE);' was called in the dialog cpp, the contents of m_strNameKey was displayed on screen in the edit control. if 'UpdateData(TRUE)' was called the DoDataExchange function would get the screen value from the edit control and put it into the member variable.

so if we set the member variable in the ParseParam function to the dialog object, you would see the argument value in the name key on your screen since the OnInitDialog function of your dialog class calls 'UpdateData(FALSE);' after loading the dialog form and attaching the controls.

for the new functionality 'Update Name' you need two keys. the 'old' name and the 'new' name. since currently we only have one edit field, i told you to add a second edit field

New Name Key: [___________________]

to the dialog form, and use the wizard to create a member for the edit control 'm_editNewName' and CString member 'm_strNewName'. if done, you also would see the new name in your dialog form (if ParseParam works as expected).

the next step would be to add a button for doing the update. if that works in the dialog, we could add another argument 'silent=yes' to the arguments. then the dialog would not show up (hidden) but the button 'update name' would be clicked programatically.

Sara
Many many thanks Sara.

all string arguments to CString member functions need to be wide characters. so change "old" and "new" and "do" and "updnam" to _T("old"), _T("new"), _T("do"), _T("updnam").

Open in new window


where should I perform such change?
Please omit the current reply in above.

for the new functionality 'Update Name' you need two keys. the 'old' name and the 'new' name. since currently we only have one edit field, i told you to add a second edit field

New Name Key: [___________________]

to the dialog form, and use the wizard to create a member for the edit control 'm_editNewName' and CString member 'm_strNewName'. if done, you also would see the new name in your dialog form (if ParseParam works as expected).

must I call the wizard for doing this, to the Dialog? Can I have more details to call the wizard?


the next step would be to add a button for doing the update. if that works in the dialog, we could add another argument 'silent=yes' to the arguments. then the dialog would not show up (hidden) but the button 'update name' would be clicked programatically.

where should I add the button?
must I call the wizard for doing this
no. you should add both the controls (static text control and edit control) with the resource view editor since a manual edition of resources is labourious and error-prone. don't be afraid of trying new features in resource editor. you could make multiple 'undo' by ctrl+z even if you changed a lot. if you select multiple controls you can move them with arrow keys. if you hold the shift-key you could make them wider or smaller with the arrow keys. you can use the align minibuttons to if you selected multiple controls. the last one selected is the one whcih determines the new size, the new distance, or the alignment border. you also could copy a control or multiple controls to clipboard (ctrl+c) and then copy them by ctrl+v. the new controls are already selected and you could move them to a new place by means of the arrow keys or mouse. don't forget to edit the properties of (the) new controls and set new IDC_STAT_NEWNAME and IDC_EDIT_NEWNAME resource ids same as it is with the already existing controls.

after this you could search for example for IDC_STAT_ITEMNUM  in *.h;*.cpp files and make copies of the found statements for the new IDC_STAT_NEWNAME. also make copies of statements with  IDC_EDIT_ITEMNUM and replace them with IDC_EDIT_NEWNAME. after that make copies of statements with m_statItemNum, m_editItemNum, m_strItemNum in header and cpp files and replace by m_statNewName, m_editNewName, m_strNewName.

perhaps you find it easier to use the wizard in resource editor:

- click on the new static text control such that it is selected
- right-click and choose add member variable
- give name 'm_statNewName'
- click on the new edit control such that it is selected
- right-click and choose add member variable
- give name 'm_editNewName'
- right-click again and choose add member variable
- change combobox from 'Control' to 'Value'
- choose 'CString' for member type
- give name 'm_strNewName'

Sara
below the 'get record' button?

you also could make an own groupbox for each button with the additional input fields needed for the button. it is a design question rather than a technical question.

Sara

after this you could search for example for IDC_STAT_ITEMNUM  in *.h;*.cpp files and make copies of the found statements for the new IDC_STAT_NEWNAME. also make copies of statements with  IDC_EDIT_ITEMNUM and replace them with IDC_EDIT_NEWNAME

do I need to do the same on rc file as well?
Do I need to also duplicate this
DDX_Control(pDX, IDC_STAT_ITEMNUM, m_statItemNum);

Open in new window


for NEWNAME, that is within .cpp file?
do I need to do the same on rc file as well?
no, if you added the controls by using the resource view editor what is highly recommended the entries already are in .rc file (and resource.h)

the static control member was not used (yet) in dialog cpp. but if we want to show/hide controls on the screen depending on action code, we would need the control members. see, static controls for file numbers which were enabled/disabled/shown/hidden depending on radio button selection.

Sara
How about the 2nd question in above? Many thanks
Do I need to also duplicate this
DDX_Control(pDX, IDC_STAT_ITEMNUM, m_statItemNum);

Open in new window


for NEWNAME, that is within .cpp file?
How about the 2nd question in above?
i answered in the second section of my last comment. it was yes.

Sara
note, if using the wizard it could be done in less than a minute and it would work without issues.

doing it manually, creates questions which actually were already answered a few times. it also requires a rough understandness what the code to add is doing.

Sara
Many thanks Sara.
Is it fine to have
	...
	DDX_Control(pDX, IDC_STAT_NEWNAME, m_statNewName);
	DDX_Control(pDX, IDC_EDIT_NEWNAME, m_editNewName);
	...
	

Open in new window


should I declare both "m_statNewName" and "m_editNewName"?
yes, you should copy each statement where m_statItemNum and m_editItemNum occured and replace it withe the new names. this must be done in all cpp files and all header files. doing the latter you find occurences in binaryfileviewerdlg.h such that you 'declare' the new members in the class header that way.

in resource.h you don't need to add since that already was done by the resource editor.

Sara
Very sorry Sara.

Can I have more details to create the button using the wizard?
- click to the 'get record' button with the mouse
- keep the ctrl key pressed and "copy" the button by "dragging" the copied button below the 'get record' button.
- if you select both buttons (also with the ctrl key pressed) - first the new button - second the 'get record' button you can align the new button using the mini button |-
- if you click again to the new button without ctrl key, it is selected solely
- do alt+enter to open the properties (if not already open)
- change 'Get Record' by 'Update Name'
- change IDC_BUT_GETRECORD2 to IDC_BUT_UPDNAM
- right-click to new button and 'add event handler'
- choose BN_CLICKED and create the handler function.

Sara
Many thanks Sara.

within "Solution explorer", how can I get into the form, to be able to see "get record" button?
you either use resource view tab (which is beside solution explorer tab) or you click to binaryfileviewer.rc below 'resources' in solution explorer tree or you use menu item 'view - resource view'. if resource view is open, open 'dialog' folder and resource 'IDD_BINARYFILEVIEWER_DIALOG'.

if you get error '... is already open in another editor' you need to close either binaryfileviewer.rc or resource.h since one or both of them are open in a text editor. you find all open source files by clicking to little 'arrow down' button most right in the title bar with file names or by menu item 'window - windows...'.

Sara
Many thanks Sara.
Any advice to this
User generated image
I got?
didn't you read my last comment?

Sara
close rc file and resource.h both opened in text mode. then resource view will open the resources explorer-like as a tree.

you also should "dock" resource view beside solution explorer.

Sara
Sorry Sara, there are still few problems and can you please advise?
	1	IntelliSense: argument of type "const char *" is incompatible with parameter of type "LPCWSTR"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	58	29	BinaryFileViewer
	2	IntelliSense: argument of type "const char *" is incompatible with parameter of type "LPCWSTR"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	62	34	BinaryFileViewer
	3	IntelliSense: class "CBinaryFileViewerDlg" has no member "m_strNewName"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	65	13	BinaryFileViewer
	4	IntelliSense: argument of type "const char *" is incompatible with parameter of type "LPCWSTR"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	67	34	BinaryFileViewer
	5	IntelliSense: argument of type "const char *" is incompatible with parameter of type "LPCWSTR"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	69	30	BinaryFileViewer
	6	IntelliSense: class "CBinaryFileViewerDlg" has no member "m_eCmdLineAction"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	71	14	BinaryFileViewer

Open in new window

you have to change all literals in quotes like "some contents" to _T("some contents").

actually you already asked the same thing in some previous questions above,

class "CBinaryFileViewerDlg" has no member "m_eCmdLineAction"      c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp      71      14      BinaryFileViewer

will you just look above, it also was explained a multiple timse that you need to add an enum type and a member variable.

Sara
note, i hope that you were able to open the resource view now. if so, you could add not only the button but also the new controls for 'New Name' as described with the resource view and the wizard.

Sara
Sorry Sara.
I did replace those IDC_STA... variables. can I have more details to the liberals you currently mentioned?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Good day Sara,
any advice to these
Error	1	error C2039: 'm_strNewName' : is not a member of 'CBinaryFileViewerDlg'	c:\binaryfileviewer 150815\binaryfileviewer\binaryfileviewer.cpp	65	1	BinaryFileViewer
	2	IntelliSense: class "CBinaryFileViewerDlg" has no member "m_strNewName"	c:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.cpp	65	13	BinaryFileViewer

Open in new window

you may look into this thread for 'm_strNewName', 'new name', 'IDC_EDIT_NEWNAME' and you'll find many comments. it rarely makes sense to add the same information again.

Sara
Sorry, how about this

Error	1	error RC2104: undefined keyword or key name: NUM	C:\BinaryFileViewer 150815\BinaryFileViewer\BinaryFileViewer.rc	129	1	BinaryFileViewer

Open in new window

that means that the rc file is corrupt at least in the line where the 'NUM' keyword was used. i assume you 'edited' the rc file by accident while it was open in text mode. if you post the rc file in a code window i could try to repair it. you could try yourself by locating 'NUM' in the rc file and look whether you made a new line by accident. you find the valid keys in resource.h like IDC_RAD_NUMBER, IDC_EDIT_NAME_FILNUM, IDC_STAT_RECNUM, .... more.

Sara
the wrong ID is in line 129

LTEXT           "Item Number", NUM, 424, 71, 43, 9, NOT WS_GROUP

the original ID has been IDC_STAT_ITEMNUM what you can find out if you were looking into mfcapplication9.rc .

i don't see the new controls in the rc file you posted? you should add 'New Name' static text and edit field for the new name. you also should add button 'update name'.

also i suggested to change the groupbox 'Binary File Selection' by removing the 'File Number' controls (since it makes little sense to still support those temporary index files). instead use file paths _T("c:\\dp4\\flout.dat"), _T("c:\\dp4\\fl_name.idx"), _T("c:\\dp4\\fl_number.idx") and assign them to m_strFilePath depending on the radio button selection.

doing so, you could make the group box 'Binary File Selection' smaller and get more space for the new input fields and the new button(s).

Sara
Many thanks Sara.

i don't see the new controls in the rc file you posted? you should add 'New Name' static text and edit field for the new name. you also should add button 'update name'.

can I have more details to do these?
can I have more details to do these?
actually, i've given already too much information on these? see below. all these informations are in the current thread. there are still more if you look into older threads.

Sara

for the new name you would need to add a CString member in the dialog form.

if the CBinaryFileViewerDlg is an exact copy of CMfcApplication9Dlg beside of the name, you have for each edit control in the dialog form a CString member variable defined. for example in the form there is a edit control

Name Key : [_________________]

with IDC_EDIT_NAMEKEY  as the resource id.

if you look into cpp file for IDC_EDIT_NAMEKEY you'll see two entries in (wizard-generated) DoDataExchange function:

    DDX_Control(pDX, IDC_EDIT_NAMEKEY, m_editNameKey);
    DDX_Text(pDX, IDC_EDIT_NAMEKEY, m_strNameKey);

the first provides a member control 'm_editNameKey' of type CEdit. the second provides a CString member 'm_strNameKey'.

if 'UpdateData(FALSE);' was called in the dialog cpp, the contents of m_strNameKey was displayed on screen in the edit control. if 'UpdateData(TRUE)' was called the DoDataExchange function would get the screen value from the edit control and put it into the member variable.

so if we set the member variable in the ParseParam function to the dialog object, you would see the argument value in the name key on your screen since the OnInitDialog function of your dialog class calls 'UpdateData(FALSE);' after loading the dialog form and attaching the controls.

for the new functionality 'Update Name' you need two keys. the 'old' name and the 'new' name. since currently we only have one edit field, i told you to add a second edit field

New Name Key: [___________________]

to the dialog form, and use the wizard to create a member for the edit control 'm_editNewName' and CString member 'm_strNewName'. if done, you also would see the new name in your dialog form (if ParseParam works as expected).

the next step would be to add a button for doing the update. if that works in the dialog, we could add another argument 'silent=yes' to the arguments. then the dialog would not show up (hidden) but the button 'update name' would be clicked programatically.


for the new functionality 'Update Name' you need two keys. the 'old' name and the 'new' name. since currently we only have one edit field, i told you to add a second edit field

New Name Key: [___________________]

to the dialog form, and use the wizard to create a member for the edit control 'm_editNewName' and CString member 'm_strNewName'. if done, you also would see the new name in your dialog form (if ParseParam works as expected).


must I call the wizard for doing this, to the Dialog? Can I have more details to call the wizard?


the next step would be to add a button for doing the update. if that works in the dialog, we could add another argument 'silent=yes' to the arguments. then the dialog would not show up (hidden) but the button 'update name' would be clicked programatically.


where should I add the button?

must I call the wizard for doing this

no. you should add both the controls (static text control and edit control) with the resource view editor since a manual edition of resources is labourious and error-prone. don't be afraid of trying new features in resource editor. you could make multiple 'undo' by ctrl+z even if you changed a lot. if you select multiple controls you can move them with arrow keys. if you hold the shift-key you could make them wider or smaller with the arrow keys. you can use the align minibuttons to if you selected multiple controls. the last one selected is the one whcih determines the new size, the new distance, or the alignment border. you also could copy a control or multiple controls to clipboard (ctrl+c) and then copy them by ctrl+v. the new controls are already selected and you could move them to a new place by means of the arrow keys or mouse. don't forget to edit the properties of (the) new controls and set new IDC_STAT_NEWNAME and IDC_EDIT_NEWNAME resource ids same as it is with the already existing controls.

after this you could search for example for IDC_STAT_ITEMNUM  in *.h;*.cpp files and make copies of the found statements for the new IDC_STAT_NEWNAME. also make copies of statements with  IDC_EDIT_ITEMNUM and replace them with IDC_EDIT_NEWNAME. after that make copies of statements with m_statItemNum, m_editItemNum, m_strItemNum in header and cpp files and replace by m_statNewName, m_editNewName, m_strNewName.

perhaps you find it easier to use the wizard in resource editor:

- click on the new static text control such that it is selected
- right-click and choose add member variable
- give name 'm_statNewName'
- click on the new edit control such that it is selected
- right-click and choose add member variable
- give name 'm_editNewName'
- right-click again and choose add member variable
- change combobox from 'Control' to 'Value'
- choose 'CString' for member type
- give name 'm_strNewName'
after this you could search for example for IDC_STAT_ITEMNUM  in *.h;*.cpp files and make copies of the found statements for the new IDC_STAT_NEWNAME. also make copies of statements with  IDC_EDIT_ITEMNUM and replace them with IDC_EDIT_NEWNAME

do I need to do the same on rc file as well?

do I need to do the same on rc file as well?

no, if you added the controls by using the resource view editor what is highly recommended the entries already are in .rc file (and resource.h)

the static control member was not used (yet) in dialog cpp. but if we want to show/hide controls on the screen depending on action code, we would need the control members. see, static controls for file numbers which were enabled/disabled/shown/hidden depending on radio button selection.

Do I need to also duplicate this

DDX_Control(pDX, IDC_STAT_ITEMNUM, m_statItemNum);
for NEWNAME, that is within .cpp file?

How about the 2nd question in above?

i answered in the second section of my last comment. it was yes.

note, if using the wizard it could be done in less than a minute and it would work without issues.

doing it manually, creates questions which actually were already answered a few times. it also requires a rough understandness what the code to add is doing.

Is it fine to have

      ...
      DDX_Control(pDX, IDC_STAT_NEWNAME, m_statNewName);
      DDX_Control(pDX, IDC_EDIT_NEWNAME, m_editNewName);
      ...

should I declare both "m_statNewName" and "m_editNewName"?

es, you should copy each statement where m_statItemNum and m_editItemNum occured and replace it withe the new names. this must be done in all cpp files and all header files. doing the latter you find occurences in binaryfileviewerdlg.h such that you 'declare' the new members in the class header that way.

in resource.h you don't need to add since that already was done by the resource editor.

Can I have more details to create the button using the wizard?

- click to the 'get record' button with the mouse
- keep the ctrl key pressed and "copy" the button by "dragging" the copied button below the 'get record' button.
- if you select both buttons (also with the ctrl key pressed) - first the new button - second the 'get record' button you can align the new button using the mini button |-
- if you click again to the new button without ctrl key, it is selected solely
- do alt+enter to open the properties (if not already open)
- change 'Get Record' by 'Update Name'
- change IDC_BUT_GETRECORD2 to IDC_BUT_UPDNAM
- right-click to new button and 'add event handler'
- choose BN_CLICKED and create the handler function.