15

私の目標は、ポップアップボックスを使用して、ユーザーに入力を求めることです。私はかなり検索しましたが、ほとんどすべての結果から、messageBoxの作成は本当に簡単であることがわかりました。

MessageBox (NULL, "Hello World" , "Hello", MB_OKCANCEL);

しかし、入力を受け取るポップアップを作成することはより複雑であり、それを行う簡単な方法はありません。私がグーグルで見つけたすべての結果は2001年から2005年までのどこかで日付が付けられました。私はここでもっと簡単な解決策がここ数年で起こったかどうか尋ねていると思います。

うまくいけば、Javaのように素晴らしくて簡単なもの:

int number = JOptionPane.showInputDialog ("Enter an integer");

そうでない場合は、その方法について簡単に説明してもらえますか?


編集:私は何も動作させることができませんでした。:(最終的にJavaで作業を行うためのコードを記述し、次に.jarファイルを呼び出すためのC ++コードを1行記述しました。:-/問題は時間に敏感であるため、何もないよりはましでした。

4

8 に答える 8

8

Visual C ++ Expressを使用している場合は、ダイアログの作成に使用できる無料のリソースエディターが多数あります。ResEditは私が見つけたより良いものの1つです。

プロジェクトに追加する.RCファイルにダイアログリソースを作成する必要があります。

次に、 DialogBoxを呼び出す非常に単純なケースです。これにより、リソースファイルからダイアログボックスが読み込まれ、画面に配置されます。渡されたDialogProcは、いくつかの通知とともに呼び出されます。通常、すべてに対してFALSEを返しますが、編集コントロールをテキストで初期化する場所としてWM_INITDIALOGを処理すると、ボタンがクリックされたときにWM_COMMANDが送信されます。

于 2010-11-17T08:36:15.137 に答える
7

純粋なC++にはそのようなものはありません。基本的に、あなたがやろうとしていることは、OSへのAPI呼び出しを使用するか、QtなどのGUIライブラリを使用することによってのみ達成できます(ネイティブAPIを呼び出すよりも簡単で、マルチプラットフォームでもあるため、これをお勧めします)

Qtを使用すると、Javaで行うのとほぼ同じ方法で入力ダイアログを表示できます。

bool ok;
QString text = QInputDialog::getText(
        "MyApp 3000", "Enter your name:", QLineEdit::Normal,
        QString::null, &ok, this );
if ( ok && !text.isEmpty() ) {
    // user entered something and pressed OK
} else {
    // user entered nothing or pressed Cancel
}

Qtライブラリは次の場所からダウンロードできます:qt.nokia.com/products/developer-tools/

于 2010-11-17T04:16:37.880 に答える
3

Microsoftは、のように、最適化するのに十分なほど一般的なユースケースとは見なしていませんMessageBox。彼らは、おそらくコントロールとの複雑な相互作用を伴う、多くのコントロールを備えたダイアログをレイアウトし、ダイアログが完全に入力された後にのみ応答することを期待しています。あなたが求めているのは、その単純化されたバージョンです。

リソースエディターはダイアログを作成する最も簡単な方法ですが、無料のExpressバージョンのVisualStudioには含まれていません。プロンプト用のテキストコントロールとユーザーが入力するための編集コントロールを使用してダイアログを設計します。DialogBoxウィンドウ関数を使用してダイアログを表示し、ユーザーが[OK]ボタンまたは隅のXを押すと戻ります。ダイアログ。Microsoftには、ここにいくつかのドキュメントがあります

MFC、WTL、Qt、wxなど、プロセスを簡単にするために利用できるプラットフォームがいくつかありますが、これは純粋なWindowsAPIを使用して行う方法です。

于 2010-11-17T04:40:34.360 に答える
3

私の答えは、C++内からVBScript関数をロードして呼び出す方法に対するStephenQuanの答えに基づいていますか?CPPファイルのコードコメントから収集できるように、完全なUTF-8サポートが追加されました。Microsoft Script Controlを使用してInputBoxを作成するのとは異なり、これはx86およびx64の実行可能ファイル、ライブラリ、およびコントロールで使用できます。

"inputbox.h":

extern "C" char *InputBox(char *Prompt, char *Title = (char *)"", char *Default = (char *)"");
extern "C" char *PasswordBox(char *Prompt, char *Title = (char *)"", char *Default = (char *)"");

"inputbox.cpp":

#include "inputbox.h"

// Windows API
#include <windows.h>

// VBScript InputBox
#include <atlbase.h>
#include <activscp.h>
#include <comdef.h>

// UTF-8 Support
#include <wchar.h>
#include <string>
#include <vector>

using std::string;
using std::wstring;
using std::vector;

static wstring StringWiden(string Str) {
  const size_t wchar_tCount = Str.size() + 1;
  vector<wchar_t> Buffer(wchar_tCount);
  return wstring { Buffer.data(), (size_t)MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), -1, Buffer.data(), wchar_tCount) };
}

static string StringShorten(wstring Str) {
  int nBytes = (size_t)WideCharToMultiByte(CP_UTF8, 0, Str.c_str(), (int)Str.length(), NULL, 0, NULL, NULL);
  vector<char> Buffer((size_t)nBytes);
  return string { Buffer.data(), (size_t)WideCharToMultiByte(CP_UTF8, 0, Str.c_str(), (int)Str.length(), Buffer.data(), nBytes, NULL, NULL) };
}

static string StringReplaceAll(string Str, string SubStr, string NewStr) {
  size_t Position = 0;
  const size_t SubLen = SubStr.length(), NewLen = NewStr.length();
  while ((Position = Str.find(SubStr, Position)) != string::npos) {
    Str.replace(Position, SubLen, NewStr);
    Position += NewLen;
  }
  return Str;
}

static string CPPNewLineToVBSNewLine(string NewLine) {
  size_t Position = 0;
  while (Position < NewLine.length()) {
    if (NewLine[Position] == '\r' || NewLine[Position] == '\n')
      NewLine.replace(Position, 2, "\" + vbNewLine + \"");
    Position += 1;
  }
  return NewLine;
}

class CSimpleScriptSite :
  public IActiveScriptSite,
  public IActiveScriptSiteWindow {
public:
  CSimpleScriptSite() : m_cRefCount(1), m_hWnd(NULL) { }

  // IUnknown
  STDMETHOD_(ULONG, AddRef)();
  STDMETHOD_(ULONG, Release)();
  STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject);

  // IActiveScriptSite
  STDMETHOD(GetLCID)(LCID* plcid) { *plcid = 0; return S_OK; }
  STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) { return TYPE_E_ELEMENTNOTFOUND; }
  STDMETHOD(GetDocVersionString)(BSTR* pbstrVersion) { *pbstrVersion = SysAllocString(L"1.0"); return S_OK; }
  STDMETHOD(OnScriptTerminate)(const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo) { return S_OK; }
  STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) { return S_OK; }
  STDMETHOD(OnScriptError)(IActiveScriptError* pIActiveScriptError) { return S_OK; }
  STDMETHOD(OnEnterScript)(void) { return S_OK; }
  STDMETHOD(OnLeaveScript)(void) { return S_OK; }

  // IActiveScriptSiteWindow
  STDMETHOD(GetWindow)(HWND* phWnd) { *phWnd = m_hWnd; return S_OK; }
  STDMETHOD(EnableModeless)(BOOL fEnable) { return S_OK; }

  // Miscellaneous
  STDMETHOD(SetWindow)(HWND hWnd) { m_hWnd = hWnd; return S_OK; }

public:
  LONG m_cRefCount;
  HWND m_hWnd;
};

STDMETHODIMP_(ULONG) CSimpleScriptSite::AddRef() {
  return InterlockedIncrement(&m_cRefCount);
}

STDMETHODIMP_(ULONG) CSimpleScriptSite::Release() {
  if (!InterlockedDecrement(&m_cRefCount)) {
    delete this;
    return 0;
  }
  return m_cRefCount;
}

STDMETHODIMP CSimpleScriptSite::QueryInterface(REFIID riid, void **ppvObject)
{
  if (riid == IID_IUnknown || riid == IID_IActiveScriptSiteWindow) {
    *ppvObject = (IActiveScriptSiteWindow*)this;
    AddRef();
    return NOERROR;
  }
  if (riid == IID_IActiveScriptSite) {
    *ppvObject = (IActiveScriptSite*)this;
    AddRef();
    return NOERROR;
  }
  return E_NOINTERFACE;
}

static HHOOK hHook = 0;
static bool HideInput = false;

static LRESULT CALLBACK InputBoxProc(int nCode, WPARAM wParam, LPARAM lParam) {
  if (nCode < HC_ACTION)
    return CallNextHookEx(hHook, nCode, wParam, lParam);
  if (nCode = HCBT_ACTIVATE) {
    if (HideInput == true) {
      HWND TextBox = FindWindowExA((HWND)wParam, NULL, "Edit", NULL);
      SendDlgItemMessageW((HWND)wParam, GetDlgCtrlID(TextBox), EM_SETPASSWORDCHAR, L'\x25cf', 0);
    }
  }
  if (nCode = HCBT_CREATEWND) {
    if (!(GetWindowLongPtr((HWND)wParam, GWL_STYLE) & WS_CHILD))
      SetWindowLongPtr((HWND)wParam, GWL_EXSTYLE, GetWindowLongPtr((HWND)wParam, GWL_EXSTYLE) | WS_EX_DLGMODALFRAME);
  }
  return CallNextHookEx(hHook, nCode, wParam, lParam);
}

static char *InputBoxHelper(char *Prompt, char *Title, char *Default) {
  // Initialize
  HRESULT hr = S_OK;
  hr = CoInitialize(NULL);
  CSimpleScriptSite* pScriptSite = new CSimpleScriptSite();
  CComPtr<IActiveScript> spVBScript;
  CComPtr<IActiveScriptParse> spVBScriptParse;
  hr = spVBScript.CoCreateInstance(OLESTR("VBScript"));
  hr = spVBScript->SetScriptSite(pScriptSite);
  hr = spVBScript->QueryInterface(&spVBScriptParse);
  hr = spVBScriptParse->InitNew();

  // Replace quotes with double quotes
  string strPrompt = StringReplaceAll(Prompt, "\"", "\"\"");
  string strTitle = StringReplaceAll(Title, "\"", "\"\"");
  string strDefault = StringReplaceAll(Default, "\"", "\"\"");

  // Create evaluation string
  string Evaluation = "InputBox(\"" + strPrompt + "\", \"" + strTitle + "\", \"" + strDefault + "\")";
  Evaluation = CPPNewLineToVBSNewLine(Evaluation);
  wstring WideEval = StringWiden(Evaluation);

  // Run InpuBox
  CComVariant result;
  EXCEPINFO ei = {};
  DWORD ThreadID = GetCurrentThreadId();
  HINSTANCE ModHwnd = GetModuleHandle(NULL);
  hr = pScriptSite->SetWindow(GetAncestor(GetActiveWindow(), GA_ROOTOWNER));
  hHook = SetWindowsHookEx(WH_CBT, &InputBoxProc, ModHwnd, ThreadID);
  hr = spVBScriptParse->ParseScriptText(WideEval.c_str(), NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei);
  UnhookWindowsHookEx(hHook);

  // Cleanup
  spVBScriptParse = NULL;
  spVBScript = NULL;
  pScriptSite->Release();
  pScriptSite = NULL;
  CoUninitialize();

  // Result
  static string strResult;
  _bstr_t bstrResult = (_bstr_t)result;
  strResult = StringShorten((wchar_t*)bstrResult);
  return (char*)strResult.c_str();
}

char *InputBox(char *Prompt, char *Title, char *Default) {
  HideInput = false;
  return InputBoxHelper(Prompt, Title, Default);
}

char *PasswordBox(char *Prompt, char *Title, char *Default) {
  HideInput = true;
  return InputBoxHelper(Prompt, Title, Default);
}

上記の2つのファイルを作成し、それらをVisualStudioプロジェクトに追加します。

入力ボックスまたはパスワードボックスの機能(ヘッダーにあります)が必要なファイルには、ヘッダーを含めるだけです。

#include "inputbox.h"

// use functions here

また、VBScript InputBoxのタイトルバーにあるデフォルトのWindowsアプリケーションアイコンを削除しました。これは、私が見た多くの人が、そこに表示されるのがいかに醜いかについて不満を言っているためです。

ご不明な点がございましたら、お気軽にお問い合わせください。

于 2018-10-15T00:23:49.553 に答える
2

私は昔から入力ボックスの方法であまり多くのことをしていないことを認めなければなりませんが、基本的には、あらゆる種類のグラフィカル入力ボックスを取得するためにC++の外に出なければなりません。移植性の理由から、そのようなもののために言語に組み込まれたメカニズムはありません。それがC++にも適用されたかどうかは覚えていませんが、Cはあなたがコンソールを持っているとさえ想定していません。とにかく、最善の策は、Win32 API、Qtなど、すでに試していたものに沿ったものです。ただし、コンソールを使用できる場合は、iostreamライブラリを使用して作業を完了してください。

于 2010-11-17T04:15:35.110 に答える
1

コンソールウィンドウの使用は、プログラムがユーザーにプロンプ​​トを表示し、続行し、ユーザーに再度プロンプトを表示するなどの通信モードに適しています。

cinそのためには、やのような標準ライブラリの機能を使用できますcout

于 2010-11-17T04:37:11.887 に答える
1

Visual Basicや他の言語とは異なり、C++のコマンドのような「組み込み」の入力ボックスはありません。呼び出すことができるMessageBoxとは異なり、InputBox()を記述する必要があります。実際、私はそうしました。次の記事では、このようなInputBoxを、リソースなしでWin32c++プログラムから使用できる小さな静的ライブラリの一部として実装する方法について説明します。Githubのソースコード。次のように使用できます。

LPWSTR GetString(LPCTSTR szCaption, LPCTSTR szPrompt, LPCTSTR szDefaultText = L"");

例えば:

LPWSTR result = SG_InputBox::GetString(
     L"Code Project Demo", 
     L"What is your name");
于 2019-08-01T19:25:56.177 に答える
0

これを試してください: C++vs2010のInputBox

#include "stdafx.h"
#using <system.windows.forms.dll>
#using <Microsoft.VisualBasic.dll>

using namespace System;

int main(array<System::String ^> ^args)
{
    Microsoft::VisualBasic::Interaction::InputBox(L"Hello", L"Title", L"DefResp", 500, 500);
    return 0;
}
于 2016-10-02T21:25:29.023 に答える