Sign in to follow this  
caseyd

Win32 API input box

Recommended Posts

Is there a Win32 API equivalent of Java's JOptionPane.showInputDialog? It basically just pops open a small dialog window with a text input and a couple of buttons. Am I going to have to create the window myself and just show that? Thanks, Casey

Share this post


Link to post
Share on other sites
As far as I know, there isn't one. Which is a shame, there's several times that I've wanted a simple one line input box :(

Share this post


Link to post
Share on other sites
Here, I made one:

#include <windows.h>
#include <string>

#ifdef UNICODE
typedef std::wstring InputBoxStringType;
typedef LPWSTR InputBoxCharPointerType;
typedef wchar_t InputBoxCharType;
#define InputBoxString(x) L##x
#else
typedef std::string InputBoxStringType;
typedef LPSTR InputBoxCharPointerType;
typedef char InputBoxCharType;
#define InputBoxString(x) x
#endif

LRESULT CALLBACK InputBoxWndProc(HWND WndHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
static InputBoxStringType *Results = 0;
static HWND InputLabelHandle = 0;
static HWND InputHandle = 0;

switch(Message)
{
case WM_NCCREATE:
{
Results = (InputBoxStringType*)((CREATESTRUCT*)lParam)->lpCreateParams;
break;
}

case WM_CLOSE:
case WM_DESTROY:
{

PostQuitMessage(0);
break;
}

case WM_COMMAND:
{
int NotifyCode = HIWORD(wParam);
int ControlId = LOWORD(wParam);
HWND ControlHandle = (HWND)lParam;

switch(ControlId)
{
case 1001:
{
InputHandle = ControlHandle;
break;
}

case 1002:
{
if(InputHandle == 0 || !Results)
{
PostQuitMessage(0);
break;
}

InputBoxCharPointerType Buffer = new InputBoxCharType[256];
GetWindowText(InputHandle, Buffer, 256);
*Results = Buffer;
PostQuitMessage(0);
break;
}

case 1003:
{
if(InputHandle == 0 || !Results)
{
PostQuitMessage(0);
break;
}

*Results = InputBoxString("");
PostQuitMessage(0);
break;
}
}
break;
}
}
return DefWindowProc(WndHandle, Message, wParam, lParam);
}

static InputBoxStringType ShowInputBox(HWND OwnerWindowHandle, const InputBoxStringType &InputLabel, const InputBoxStringType &InputText, const InputBoxStringType &Title)
{
WNDCLASS WndClass;
HWND DialogHandle = 0;
HWND InputLabelHandle = 0;
HWND InputHandle = 0;
HWND OkButtonHandle = 0, CancelButtonHandle = 0;
InputBoxStringType Result = InputBoxString("");

ZeroMemory(&WndClass, sizeof(WNDCLASS));
WndClass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
WndClass.hIcon = LoadIcon(0, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(0, IDC_ARROW);
WndClass.hInstance = GetModuleHandle(0);
WndClass.lpszClassName = InputBoxString("InputBox");
WndClass.lpfnWndProc = InputBoxWndProc;
RegisterClass(&WndClass);

int X = 0, Y = 0;
int Width = 0, Height = 0;
RECT TempRect;
GetWindowRect(GetDesktopWindow(), &TempRect);
Width = (int)((float)(TempRect.right - TempRect.left) * 0.25f);
Height = 150;
X = ((TempRect.right - TempRect.left) / 2) - (Width / 2);
Y = ((TempRect.bottom - TempRect.top) / 2) - (Height / 2);
DialogHandle = CreateWindowEx(0, InputBoxString("InputBox"), Title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, X, Y, Width, Height, OwnerWindowHandle, 0, GetModuleHandle(0), (LPVOID)&Result);

int LabelX = 5, LabelY = 5;
int LabelWidth = Width - 10, LabelHeight = 24;
InputLabelHandle = CreateWindowEx(0, InputBoxString("STATIC"), InputLabel.c_str(), WS_CHILD | WS_VISIBLE, LabelX, LabelY, LabelWidth, LabelHeight, DialogHandle, 0, GetModuleHandle(0), 0);

int TBoxX = 5, TBoxY = 29;
int TBoxWidth = Width - 20, TBoxHeight = 24;
InputHandle = CreateWindowEx(0, InputBoxString("EDIT"), InputText.c_str(), WS_BORDER | WS_CHILD | WS_VISIBLE, TBoxX, TBoxY, TBoxWidth, TBoxHeight, DialogHandle, (HMENU)1001, GetModuleHandle(0), 0);

int OkBtnX = (Width / 2) - 75, OkBtnY = Height - 60;
int OkBtnWidth = 75, OkBtnHeight = 24;
OkButtonHandle = CreateWindowEx(0, InputBoxString("BUTTON"), InputBoxString("Ok"), WS_CHILD | WS_VISIBLE, OkBtnX, OkBtnY, OkBtnWidth, OkBtnHeight, DialogHandle, (HMENU)1002, GetModuleHandle(0), 0);

int CancelBtnX = (Width / 2) + 25, CancelBtnY = Height - 60;
int CancelBtnWidth = 75, CancelBtnHeight = 24;
CancelButtonHandle = CreateWindowEx(0, InputBoxString("BUTTON"), InputBoxString("Cancel"), WS_CHILD | WS_VISIBLE, CancelBtnX, CancelBtnY, CancelBtnWidth, CancelBtnHeight, DialogHandle, (HMENU)1003, GetModuleHandle(0), 0);

MSG Message;
ZeroMemory(&Message, sizeof(MSG));
while(Message.message != WM_QUIT)
{
if(PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
return Result;
}

#undef InputBoxString

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
InputBoxStringType Result = ShowInputBox(0, L"Please enter your name:", L"Unknown", L"Name Entry");
MessageBox(0, Result.c_str(), L"Your name is:", MB_OK);
return 0;
}




(Note, I am not the best Win32 programmer, so there may be a better way to handle this. It does work though.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Programmer16
Here, I made one:
*** Source Snippet Removed ***

(Note, I am not the best Win32 programmer, so there may be a better way to handle this. It does work though.)
I'd avoid PostQuitMessage, since that is usually used to terminate the whole program, not just a window. It might also be better to use a dialog rather than a window, since that'll handle the whole modal loop properly.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Quote:
Original post by Programmer16
Here, I made one:
*** Source Snippet Removed ***

(Note, I am not the best Win32 programmer, so there may be a better way to handle this. It does work though.)
I'd avoid PostQuitMessage, since that is usually used to terminate the whole program, not just a window. It might also be better to use a dialog rather than a window, since that'll handle the whole modal loop properly.


Lol, that's all foreign to me. I'll see what I can find and then re-code it.

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by Programmer16
Quote:
Original post by Evil Steve
Quote:
Original post by Programmer16
Here, I made one:
*** Source Snippet Removed ***

(Note, I am not the best Win32 programmer, so there may be a better way to handle this. It does work though.)
I'd avoid PostQuitMessage, since that is usually used to terminate the whole program, not just a window. It might also be better to use a dialog rather than a window, since that'll handle the whole modal loop properly.


Lol, that's all foreign to me. I'll see what I can find and then re-code it.

Thanks!
Actually, I'm not sure how easy it is to make a dialog without having a dialog template. Time for me to investigate too I think [smile]

EDIT: Aww, too easy. DialogBoxIndirect seems to be useful here. You could create a dialog in Visual Studio's resource editor, then lock the resource to get the actual buffer, and use that for DialogBoxIndirect. If that makes any sense...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this