We help IT Professionals succeed at work.

Code for Win32 InputBox

BeefJerky8732
on
Medium Priority
1,639 Views
Last Modified: 2008-03-03
I'm looking for code for a Win32 InputBox.

Something like a MessageBox, but that can take an input like the VB InputBox.

I'm hoping someone has already done this, or knows where to get the code.
Comment
Watch Question

Commented:
There's no such control in windows but you can make one yourself from an edit box and a couple of buttons.

Since you come from VB background you should probably use MFC (so better post your questions in the MFC area).

Check http://www.codeguru.com for tons of examples.
What is your compiler: BC, VC++, BCB ... ?

Author

Commented:
alexo,
>>There's no such control in windows but you can make one
>>yourself
I know that there is no such control, and I know I can make one.
I'm looking for one that is already made.
If someone has already done this, there's no use in me reinventing the wheel.

I'm looking for any available finished code.

>>Since you come from VB background you should probably
>>use MFC
I'm sorry, but I don't want an MFC solution.  I want something that can work in both Win32 and MFC code, and that's why I want a Win32 function/code.  No MFC.

AlexVirochovsky
>>What is your compiler: BC, VC++, BCB ... ?
I have all three compilers (BC, VC++, BCB).
I'm looking for something that can work with all three compilers, and that's why I want a Win32 solution.

I'm not asking anyone to do the code, I just looking if anyone has finished code for this requirement.

But if someone wants to do the code for me, I certainly will not complain, and I can increase this up to 300 points.

Thanks in advance.

Commented:
BCB already has an InputBox function. It's declared in Dialogs.


extern PACKAGE AnsiString __fastcall InputBox(const AnsiString ACaption, const AnsiString APrompt, const
     AnsiString ADefault);


Good luck!!

Author

Commented:
DrDelphi,
Thanks, but I'm looking for something that will work in all three compilers.
CERTIFIED EXPERT
Author of the Year 2009
Commented:
Here Ya go!
//-------------------------------------- the .H file

//-------------- global fn, so available like MessageBox()
extern int InputBox( HWND hWndParent, char* pszPrompt, char* pszTitle, char* pszBuf=0, int nBufLen=0 );

class CInputBox {
public:
    CInputBox();
    CInputBox( HWND hWndParent, char* pszPrompt, char* pszTitle, char* pszBuf=0, int nBufLen=0 );
    int DoModal();

    char* m_pszTitle;
    char* m_pszPrompt;
    char* m_pszInputBuf;
    int   m_nMaxLenInput;
    BOOL  m_fNoCancel;
    HWND  m_hwndParent;

    DLGTEMPLATE* m_prDT;

private:
    void  DoInit();
    char  m_szDfltBuf[80];
   
    static int CALLBACK InputBoxDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
};

//-------------------------------------- the CPP file

//--------- global fn, so available like MessageBox()
int InputBox( HWND hWndParent, char* pszPrompt, char* pszTitle, char* pszBuf, int nBufLen )
{
    ASSERT( pszBuf );  // when called this way, must pass in a real buffer
    ASSERT( nBufLen ); // and its length
    CInputBox cImpBox( hWndParent, pszPrompt, pszTitle, pszBuf, nBufLen );
    int nRet= cImpBox.DoModal();
    return (nRet);
}

CInputBox::CInputBox( HWND hwndParent, char* pszPrompt, char* pszTitle, char* pszBuf/*=0*/, int nBufLen/*=0*/ ) {
    DoInit();
    if ( pszPrompt != 0 ) m_pszPrompt=  pszPrompt;
    if ( pszTitle  != 0 ) m_pszTitle=   pszTitle;
    if ( pszBuf    != 0 ) m_pszInputBuf=pszBuf;
    m_hwndParent= hwndParent;
}

CInputBox::CInputBox() { DoInit(); }
void CInputBox::DoInit() {
    m_pszTitle=     "BeefJerky8732 forgot to set a title";
    m_pszPrompt=    "BeefJerky8732 forgot to set a prompt";
    m_pszInputBuf=  m_szDfltBuf;
   *m_pszInputBuf=  0;
    m_nMaxLenInput= sizeof(m_szDfltBuf);
    m_fNoCancel=    FALSE;
    m_prDT= (DLGTEMPLATE *) pabDlgTmplt;
    m_hwndParent= ::GetActiveWindow();
}

int CInputBox::DoModal() {
    int nRet= ::DialogBoxIndirectParam( NULL, m_prDT, m_hwndParent, InputBoxDialogProc, (LPARAM)this );
    return( nRet );
}

const BYTE pabDlgTmplt[] = {
 0xC0,0x00,0xC8,0x80,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0xDD,0x00,0x59,0x00,0x00,0x00, // ?.??..........?.Y...
 0x00,0x00,0x4D,0x00,0x65,0x00,0x73,0x00,0x73,0x00,0x61,0x00,0x67,0x00,0x65,0x00,0x20,0x00,0x49,0x00, // ..M.e.s.s.a.g.e. .I.
 0x6E,0x00,0x70,0x00,0x75,0x00,0x74,0x00,0x00,0x00,0x08,0x00,0x4D,0x00,0x53,0x00,0x20,0x00,0x53,0x00, // n.p.u.t.....M.S. .S.
 0x61,0x00,0x6E,0x00,0x73,0x00,0x20,0x00,0x53,0x00,0x65,0x00,0x72,0x00,0x69,0x00,0x66,0x00,0x00,0x00, // a.n.s. .S.e.r.i.f...
 0x00,0x00,0x02,0x50,0x00,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0xD5,0x00,0x18,0x00,0xEB,0x03,0xFF,0xFF, // ...P........?...?.??
 0x82,0x00,0x28,0x00,0x70,0x00,0x72,0x00,0x6F,0x00,0x6D,0x00,0x70,0x00,0x74,0x00,0x29,0x00,0x00,0x00, // ?.(.p.r.o.m.p.t.)...
 0x00,0x00,0x00,0x00,0x80,0x00,0x81,0x50,0x00,0x00,0x00,0x00,0x04,0x00,0x26,0x00,0xD1,0x00,0x0E,0x00, // ....?..P......&.?...
 0xEA,0x03,0xFF,0xFF,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x50,0x00,0x00,0x00,0x00, // ?.??...........P....
 0xA3,0x00,0x3E,0x00,0x32,0x00,0x0E,0x00,0x01,0x00,0xFF,0xFF,0x80,0x00,0x4F,0x00,0x4B,0x00,0x00,0x00, // ?.>.2.....???.O.K...
 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x00,0x6A,0x00,0x3F,0x00,0x32,0x00,0x0E,0x00, // .......P....j.?.2...
 0x02,0x00,0xFF,0xFF,0x80,0x00,0x43,0x00,0x61,0x00,0x6E,0x00,0x63,0x00,0x65,0x00,0x6C,0x00,0x00,0x00, // ..???.C.a.n.c.e.l...
 0x00,0x00,0x00,0x00//
};
const int CNUM_EditID= 1002;
const int CNUM_PromptID= 1003;
int CALLBACK CInputBox::InputBoxDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    static CInputBox* pcThis;
    switch( uMsg ) {
        case WM_INITDIALOG:
            pcThis= (CInputBox*)lParam;
            ::SetWindowText( hDlg, pcThis->m_pszTitle );
            ::SetDlgItemText( hDlg, CNUM_PromptID, pcThis->m_pszPrompt );
            ::SetDlgItemText( hDlg, CNUM_EditID, pcThis->m_pszInputBuf ); // show starting value
            ::SetWindowText( hDlg, pcThis->m_pszTitle );
            ::ShowWindow( ::GetDlgItem( hDlg, IDCANCEL), !pcThis->m_fNoCancel );
        return( TRUE );
        case WM_COMMAND:
            switch( wParam ) {
                case IDOK:
                    ::GetDlgItemText( hDlg, IDC_EDIT1, pcThis->m_pszInputBuf, pcThis->m_nMaxLenInput );
                    ::EndDialog( hDlg, IDOK );
                return( TRUE );
                case IDCANCEL:
                    ::EndDialog( hDlg, IDCANCEL );
                return( TRUE );
            }
        break;
    }
    return ( DefWindowProc(hDlg,uMsg,wParam,lParam) );
}

... continued...
CERTIFIED EXPERT
Author of the Year 2009

Commented:
A self-contained little beauty.  No need to have a dialog box resource for it--- it makes its own.

To use it, simply...

#include InputBox.h


    CInputBox cImpBox( 0, "Prompt", "Title" );
    int nRet= cImpBox.DoModal();
// or
    char szBuf[100]="(initial value)";
    nRet= InputBox( 0, "Input something:", "Title", szBuf, sizeof(szBuf) );

If you want some pretty icons or other stuff, just modify the WM_INITDIALOG case code in the DlgProc.


-- Dan

Author

Commented:
Thanks Dan!
That is what I was looking for.

Author

Commented:
I doubled the points.
Thanks again.

Author

Commented:
Hi Dan,
I just have one question.  How can I modify your code to make it so that I can move the dialog.
The current code will not let me move the window.

Thanks in advance.

Author

Commented:
Also, is there a safe value to make IDC_EDIT1 equal to?

It's not defined in your code, so I made it equal to 1001 in the header.  But I'm worried that if I forget about this value, and I try using it in another project that is already using 1001 for a EDIT window, that this would cause problems.
Would this only be a problem if the conflicting IDC_??? where in the same window?

Author

Commented:
After playing with the code, I see that IDC_EDIT1 is wrong, and it should be CNUM_EditID.

But my question still stands.  What if I have another dialog, and it has an IDC_???? defined as 1002?
And or a read-only text field with ID of 1003?
Will there be a confict?

Author

Commented:
Also, how can I get the OK and Cancel button centered automatically?
CERTIFIED EXPERT
Author of the Year 2009

Commented:
>>The current code will not let me move the window.

You will need to use the MoveWindow API Fn in the WM_INITDIALOG case of the InputBoxDialogProc.  You could add member variables to the CInputDlg class and then use pcThis-> to access them.

>> Also, is there a safe value to make IDC_EDIT1 equal to

Use the constants that I have defined:

   const int CNUM_EditID= 1002;
   const int CNUM_PromptID= 1003;

>> What if I have another dialog, and it has an IDC_???? defined as 1002? And or a read-only text field with ID of 1003? Will there be a confict?

No.  There is no conflict because the control IDs are local to the dialog (think about it... IDOK and IDCANCEL exist for nearly all dlgs!).  There is no resource ID for the dialogbox itself, so there *can't* be a conflct with that.

>> Also, how can I get the OK and Cancel button centered automatically?

You will need to use the MoveWindow API Fn in the WM_INITDIALOG case of the InputBoxDialogProc.  For instance:

HWND hwndOK= GetDlgItem( hDlg, IDOK );
RECT rc;
GetWindowRect( hwndOK...
ScreenToClient(  hwndOK, ....
MoveWindow( hwndOK, ...

If this is difficult for you to do, make a new 100 pt question and I'll write the code (it is really outside the scope of this question, don't you think?).

-- Dan

Author

Commented:
>>If this is difficult for you to do, make a new 100 pt
>>question and I'll write the code

I think I can figure it out.

What I can not figure out, is how did you determine what setting to put in the pabDlgTmplt field.
What is your source???

If you can just point me to the right direction, I can find the info myself.

I figured out that it's an array of DLGTEMPLATE items.
But how do you know which one is for the buttons and which one is for the text fields and main window?
Where did you get your information from?