Solved

How to disable edit controls based upon a check box value?  

Posted on 2002-03-16
22
1,142 Views
Last Modified: 2013-11-14
I have an installation routine (using InstallShield) which calls a VC++ dialogue box (DLG_GETDBINFO) as a '_IsUser.dll'

This dialogue has one 'IDC_CHECK' box and four 'IDC_EDIT' boxes.  If the user checks the check-box, I want to disable two of the IDC_EDIT controls.

How is this done?  Do I need to create code using the ClassWizard?  In other words, if I right-click on the IDC_CHECK object and choose 'ClassWizard', do I have to add a class in order to dim the IDC_EDIT boxes?  Or do I do it from the isuser.c file and enter the code there?  

In either event I'm guessing I need the following:

EnableWindow(GetDlgItem(hDialog, IDC_EDIT3), FALSE);
EnableWindow(GetDlgItem(hDialog, IDC_EDIT4), FALSE);

If so, how do I get the 'hDialog' parameter?  Here's what my files look like:

resource.h

#define IDC_EDIT1                       1002
#define IDC_EDIT2                       1003
#define IDC_EDIT3                       1004
#define IDC_EDIT4                       1005
#define IDC_CHECK1                      1008
#define DLG_TEMPLATE                    13029
#define DLG_TEMPLATE2                   13030
#define DLG_GETDBINFO                   13031
#define IDC_STATIC                      -1
...
...
----------------------------------------------------------

iuser.c

#define NOCOMM
#include <windows.h>

BOOL WINAPI DllMain( PVOID hmod, ULONG ulReason, PCONTEXT pctx )
{
    return TRUE;
}
----------------------------------------------------------

Do I need to do something like the following instead:

#define NOCOMM
#include <windows.h>
#include "resource.h"


BOOL WINAPI DllMain( PVOID hmod, ULONG ulReason, PCONTEXT pctx )
{

        if(IDC_CHECK1 == TRUE){                    
          EnableWindow(GetDlgItem(DLG_GETDBINFO, IDC_EDIT3), FALSE);
         EnableWindow(GetDlgItem(DLG_GETDBINFO, IDC_EDIT4), FALSE);

    return TRUE;
}

Also, why doesn't the WINAPI entry point look more like this:

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
);
 
0
Comment
Question by:John500
  • 12
  • 9
22 Comments
 
LVL 1

Expert Comment

by:lidorc
ID: 6873489
Why dont you work with MFC and make your life a bit more simple?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6873647
If you are using MFC, just use..

  GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE);

in your CDialog-derived class.

If not, then the hDialog parameter is the HWND that is passed to your window procedure in your message pump.  If you don't have a window procedure or a message pump, or don't know what they are, then you should definately use MFC.

-- Dan
0
 

Author Comment

by:John500
ID: 6874139
DanRollins/lidorc,

Here is all that I know,

I have a dialogue box which up until now needed zero code behind it.  The user is able to input data, and InstallShield code is able to get the values entered.

Now however, since I want to disable two of the edit controls, I need to add code.  I don't know what that code should be placed, or how to do it.  If MFC is the way to go, great, how is it done?

Thanks
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6875563
I'm not sure about the connection with InstallShield.  It has a scripting language and so forth.  If you give some background, I might be able to thelp (or you can wait fro somebody else who knows...)

How did you originally create the dialog?  I mean what program were you running, and what steps did you take?

-- Dan
0
 

Author Comment

by:John500
ID: 6876854
DanRollins,

I wouldn't put too much emphasis on InstallShield.  I was just trying to give an overall picture of what I'm doing.

I made the dialog box by first creating a dll workspace because what's what InstallShield requires in order to call the dialog.  I have to identify the dll within InstallShield's workspace.  InstallShield can reference the edit controls by name, i.e. 'IDC_EDIT1'

However, I'm under the impression that InstallShield can not disable the boxes, but only extract the values entered.  I would think the VC++ code takes care of disabling the edit controls and the code should be no different from a regular executable.  Wouldn't you agree?  I've just haven't done this before....
0
 

Author Comment

by:John500
ID: 6876856
DanRollins,

I wouldn't put too much emphasis on InstallShield.  I was just trying to give an overall picture of what I'm doing.

I made the dialog box by first creating a dll workspace because what's what InstallShield requires in order to call the dialog.  I have to identify the dll within InstallShield's workspace.  InstallShield can reference the edit controls by name, i.e. 'IDC_EDIT1'

However, I'm under the impression that InstallShield can not disable the boxes, but only extract the values entered.  I would think the VC++ code takes care of disabling the edit controls and the code should be no different from a regular executable.  Wouldn't you agree?  I just haven't done this before....
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6878098
>>I made the dialog box by first creating a dll workspace

Can you elaborate?  Was the VC++ IDE involved at any point?

-- Dan
0
 

Author Comment

by:John500
ID: 6878565
Dan,

It's hard to say because it's been so long.  If I remember correctly, InstallShield provided a few bare-bones workspaces for dialogs like the one I'm using and then it's up to you to customize it.

I'm 99 % sure it would be made by creating a new Win32 Dll project.  But tell me this, why is there any thought as to how the code would be added.  Isn't there really only one option here which is to add a class to the control.  If the control (IDC_CHECK) has a class associated with it, it can utilize the code of that class, yes/no?

If the answer is yes, how would I add the class, where does the class reside?  I'm assuming the class in question is the one that has the following functions:

GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE);
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6878632
>>Isn't there really only one option here which is to
>> add a class to the control.
If you are working with MFC, then you can easily disable a button in several ways:

   GetDlgItem( IDC_EDIT3 )->EnableWindow( FALSE );
or
use the ClassWizard to add a control-style variable...

   m_ctlEdit.EnableWindow( FALSE );

If you have the ability to use Win23 API calls, you can use

    ::EnableWindow( hWndOfTheEditCtrl, FALSE );

If you are working under some bare-bones implementation defined, as say some sort of scripting language provided by some ancient version of InstallShill, then, you must realize that there is no 'pat' answer.

-- Dan
0
 

Author Comment

by:John500
ID: 6879906
Dan,

I'd like to try to add the appropriate class.  If I choose to 'Add Class', I get the following file types as my choice:

TypeLib Files(*.tlb, .olb, .dll)

After looking through the docs I can see that the 'GetDlgItem' function is in the 'CWindow' class.  One of the code samples had the following:

#include "classlib.h"

Thus, I'm guessing the appropriate library is 'classlib.h'.  If not how would I add the class?

On a slightly different note, what if I made a new project but made it an MFC AppWizard dll ?   Would this type of project automatically provide the necessary classes for the controls?

Since my present project is a Win32 dll, is this the reason I don't automatically have the CWindow class as part of the project?
0
 

Author Comment

by:John500
ID: 6880031
Dan,

I rebuilt the dialog and made it an MFC AppWizard dll.  It was easy and the classes I needed were automatically available.  I built and ran the dialog (separately from InstallShield) and it works fine.

However, InstallShield expects to reference a file with a dll extension but the MFC dll has .exe extension.  Any idea why this happen.  Why would the Project be called a dll yet produce an exe?  Any work arounds here?
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:John500
ID: 6880648
Dan,

I must have made an '.exe' by mistake.  I did it again and was able to make a dll.  However, after I udated the InstallShield project to include the new file, InstallShield reported it was unable to display the dialog during runtime.

I really don't think it has anything to do with InstallShield.  I did run across the following note located in the dll code or the C++ file:

//     Note!
//
//          If this DLL is dynamically linked against the MFC
//          DLLs, any functions exported from this DLL which
//          call into MFC must have the AFX_MANAGE_STATE macro
//          added at the very beginning of the function.
//
//          For example:
//
//          extern "C" BOOL PASCAL EXPORT ExportedFunction()
//          {
//               AFX_MANAGE_STATE(AfxGetStaticModuleState());
//               // normal function body here
//          }
//
//          It is very important that this macro appear in each
//          function, prior to any calls into MFC.  This means that
//          it must appear as the first statement within the
//          function, even before any object variable declarations
//          as their constructors may generate calls into the MFC
//          DLL.
//
//          Please see MFC Technical Notes 33 and 58 for additional
//          details.
//

Do you think I need to do this in IDC_CHECK1 control?  Here is the way the code looks now:

// IsUser_Dialog message handlers

void IsUser_Dialog::OnCheck1()
{
     GetDlgItem(IDC_EDIT3)->EnableWindow( FALSE );
     GetDlgItem(IDC_EDIT4)->EnableWindow( FALSE );    
}
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6881082
Does the InstallShield documentation say about what functions the DLL is supposed to Export?

Perhaps it does not use any of the code in the DLL, only the dialog template.  If that is the case, then you will not be able enable/disable controls based upon events.

So, why isn't InstallSheild finding the dialog?  Check its ID very carefully against the value that InstallShield expects to see.  the numerical valu of the ID has likely changed with all of these tests you have been doing.

-- Dan
0
 

Author Comment

by:John500
ID: 6894199
Dan,

I was able to dim the fields using the InstallShield code.  It wasn't very obvious but I found it in some example code.  Thus, I won't have to add MFC code.

What's the chances of finishing this question on a different note.  That is, I want to add a 'Browse' button to the same dialog box.  How would I provide myself the ability to use a control like that.  In other words, the toolbar named 'Controls' doesn't include a 'Browse' button.

I tried to create one by adding a custom button, but something didn't work right?  What do you think?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6895261
>> want to add a 'Browse' button

I think the answer to that is related to this comment:

>> was able to dim the fields using the InstallShield code.  It wasn't very obvious but...

I think you will need to check the InstallShield documentation.  If they support doing something on a click of a user-identified button and if one of the things you can do is bring up a Browse-forFOlder or Browse-for-File  dialog, then there you go!  Otherwise, it is not possible.

-- Dan
0
 

Author Comment

by:John500
ID: 6896357
Ok, but are you saying VC doesn't allow you to add a browse control to a dialog?  Although I can 'control' my dialog objects using InstallShield, I can't add objects to the dialog from InstallShield.  That has to be done in VC, how is that done?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6897045
Are we talking about the same thing here?  A 'a browse control' is just a button (typically with a title of 'Browse...').  When clicked, it displays a new dialog that lets the user select a file or a folder.  I think that you *can* add buttons to your DLL dialog resource.  But that does not solve the problem unless InstallSheild provides a means to process the click of that button.

-- Dan
0
 

Author Comment

by:John500
ID: 6897151
Yes, InstallShield provides a means to process the button, I just need to know:

1) Why Visual Studio doesn't make that button part of the standard set of controls.  

2) Thus, where the hell is that control located...
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6897328
It is in the palette of controls, visible when in the Dialog Editor.  It looks like a button, only smaller.

-- Dan
0
 

Author Comment

by:John500
ID: 6897566
For some reason, this control is not on my control toolbar.   It's definitely not there.  What pain in the but this thing is....

I'm pretty familiar with Visual Studio, but this happens to be the first time I needed to add a browse button.

I know that within VB, I would go to the following menu to add a control:

Project\Components\

Then for example, I would check the following box :

Microsoft Windows Common Controls-36.0 (SP4)

Is there something I have to do to get the 'Browse' control to appear?


0
 
LVL 49

Accepted Solution

by:
DanRollins earned 100 total points
ID: 6897592
There is no special control for 'Browse for folder' or 'Browse for file.'  There is only standard button and when that button is clicked, you handle that event.  In handling that event, you use the Common Dialog access function GetOpenFilename() or perhaps SHBrowseForFolder() API call.

The button is in the palette: Third from the top on the right, directly above the radio button.

-- Dan
0
 

Author Comment

by:John500
ID: 6899301
Dan,

Thanks.  I used the 'button' as you said and used InstallShield's function 'SelectDirEx()' to display the folder...

Thanks again for the help!
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now