Win32/64ネットワーク開発 002 wininetを使ったhttp通信

提供:yonewiki
2023年11月7日 (火) 00:27時点におけるYo-net (トーク | 投稿記録)による版 (→‎概要)

Win32/64 ネットワーク処理開発へ戻る。

概要

 またまた、あまり使い道が思いつかないライブラリを使ってみます。wininetライブラリというものです。通信してるなぁって感じはします。


 VisualStudioでソリューションエクスプローラからプロジェクト名の項目を選択した状態で、メニューの[プロジェクト(P)]-[プロパティ(P)]を選択して表示されるダイアログボックスの[リンカー]-[入力]から[追加の依存ファイル]の項目に「wininet.Lib」を追記します。追記するときは「;」がデリミタ(区分け記号)として必要ですので、規定値を消さずに、追記するには、


$(CoreLibraryDependencies);%(AdditionalDependencies);wininet.Lib


のような形式になるでしょう。またプログラムを書くときには#include <wininet.h>のようにしてwininet.hファイルをインクルードする必要があります。ここでは、基本のアプリ(Win32/64アプリ開発 001 基礎Win32/64アプリ開発 002 基礎の理解Win32/64アプリ開発 002 基礎の理解)にメニューを追加して、選択した項目からダイアログを表示して、URLの入力を受け取りwininetライブラリの関数を使ってみたいと思います。


 メニュー追加から説明ですね。イチカラじゃないのがやさしくないよね。わかってる。でも基本のアプリは紹介したから、そこを見てほしいんですよね。


 メニューを追加するには、リソースエディタでメニューを作成します。ソリューションエクスプローラーに表示されている「****.rc」という項目をダブルクリック選択して、リソースビュータブに切り替えます。リソースの項目が一つでもコード表示されているとリソースビューのUI表示可能状態にはならないので、そこには注意が必要です。言葉で説明すると難しい複雑さがありますね。リソースビューのトップフォルダを右クリックして表示されるメニューから「リソースの追加」を選択します。表示されたダイアログで「MENU」を選択します。リソースビューでこれから作成するメニューを青色選択状態にすると、プロパティビューに表示された項目IDの欄の値が編集できます。ID_MENUという名前にしましょうか?MENUでもいいですけど今後の説明でMENUと記述したときにIDのことをいっているのかMENUという機能の話をしているかわからなくなるので、ID_MENUとさせていただきました。


 編集ビューでUIを伴って、メニューが作れます。直感的に操作できます。ここに入力とあるところに文字列を入力すると、メニューの外観が入力した通りになります。メニューを選択したときに選択した項目が何であるかを意味するIDというものを設定する必要があります。ここに入力とあるところに入力した文字はメニュー項目のキャプションと呼びます。それは、プロパティビューでも確認できるようになっています。項目を青色選択している状態では、プロパティビューのキャプションという項目があって、今まさに入力した内容が反映されるようになっています。キャプションの欄に次のように入力してみましょう。「URL(&U)...」このように(&U)のような指定をするとメニュー選択ショートカットとして振る舞います。メニューはキーボードで操作しやすくなり、[Alt]→[U]のように操作するとメニューが選択できるようになります。...は選択するとまだ処理が即実行されず、さらに何か聞いてくるダイアログが開くなりするだけの処理だよという動作を意味しています。...もつけておくと親切でしょう。キャプションを「URL(&U)...」としたところと同じ部分にIDという項目もあります。これがメニュー項目を選択したときのIDになります。ここでは「IDM_URL」のように名前をつけておきましょう。これでリソースの保存をするために保存ボタンを押すか、[Ctrl]+[s]と操作をしましょう。


そして、WNDCLASS型の変数に各情報を設定してRegisterClassEx関数で登録する部分で


WNDCLASS WNDCLASSwc = {0};

WNDCLASSwc.lpszMenuName = L"ID_MENU";


のようにメニューのIDを指定します。


次にDialog、選択した後に開くダイアログを作りましょう。リソースの作成から先ほどは[MENU]と選択したところを、[Dialog]-[IDD_PROPPAGE_SMALL]と選択します。Dialogが作成されます。


 いろいろ操作してコントロールを配置したいところですが、説明するのも、作る方も大変なので、コードを打ち込んだ方が楽なのでそのようにしてみましょう。リソース系の編集ウィンドウをすべて閉じて、ソリューションエクスプローラから「****.rc」を右クリックして表示されるメニューから[コードの表示]を選択します。リソースビューを閉じるかを聞かれたら閉じるを選択します。そしたら、コードが表示されるはずです。これが、UIを使って操作してできたリソースコードの本体です。所詮はただの文字列です。このなかから、


IDD_PROPPAGE_SMALL DIALOGEX … … … END


 というカタマリを見つけて、以下のように打ち変えます。


ID_DIALOG_URL DIALOGEX 0, 0, 256, 47
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "URL"
FONT 9, "MS ゴシック", 400, 0, 0x80
BEGIN
    EDITTEXT        IDC_URL,39,7,210,13,ES_AUTOHSCROLL
    PUSHBUTTON      "閉じる",IDCANCEL,149,27,72,13
    LTEXT           "URL",IDC_STATIC,7,7,23,10
    DEFPUSHBUTTON   "接続",IDC_CONNECT,34,27,72,13
END


 のようにします。これで保存して、エディタを閉じて再度リソースエディタで開いてみるとダイアログが完成しています。URLを入力する欄と、ボタンが2つと、入力欄の横のテキスト(スタティックテキストと呼びます)があることが確認できます。UIでやると手数が増えることもあるということですね。このようにUIを使いこなす手順と、リソースをコードで直接編集する手順を知っていると楽ができます。ただし、リソースのコードがVisual Studioが読み取れないほどにルールに反していると二度とリソースをコンパイルすることも、エディタでみることもできなくなりますので、深い理解も必要です。


 更に、コードを変更していきます。メニューから飛んできたIDM_URLを受け取ったら、ダイアログを表示するようにコードを追加します。


LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
    switch(msg){

	case WM_COMMAND:
		switch (LOWORD(wp)) {//wpはMainウィンドウプロシージャーが受け取る第3引数のWPARAM型
		case IDM_URL:
			DialogBox(HINSTANCEinst,//HINSTANCEinstはWinMain関数の第1引数の値。
				L"ID_DIALOG_URL",
				hWnd,//hWndはMainウィンドウプロシージャーが受け取る第1引数のHWND型
				(DLGPROC)UrlDialogProc);
			break;
		}
		break;

    }
}


 このようにDialogBox関数でリソースで定義したID_DIALOG_URLというダイアログが呼び出せます。ダイアログ用のプロシージャ関数を定義しましたので、


<syntaxhighlight lang="cpp"> BOOL CALLBACK UrlDialogProc(HWND, UINT, WPARAM, LPARAM); </syntaxhighlihgt>


というプロトタイプ宣言や


<syntaxhighlight lang="cpp"> BOOL CALLBACK UrlDialogProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp){ switch (msg) {

   …
   }

} </syntaxhighlihgt>


のようなダイアログメッセージプロシージャ関数本体が必要です。そうして、インターネット接続をして、urlが示すアドレスにhttp応答を呼び掛けて、受け取るという処理を行います。


<syntaxhighlight lang="cpp"> char pchStrUrl[2083] = "";//IEのURL最大文字数 グローバル変数 BOOL CALLBACK UrlDialogProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp){ switch (msg) { case WM_INITDIALOG: SetDlgItemText(hDlg, IDC_URL, pchStrUrl); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDC_CONNECT: GetDlgItemText(hDlg, IDC_URL, pchStrUrl, (int)sizeof(pchStrUrl)); EndDialog(hDlg, IDOK); HttpConnect(); return TRUE; case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE; } return FALSE; } return FALSE; } </syntaxhighlihgt>


 と上記のように、pchStrUrlという文字列グローバル変数(これは暫定的な簡単なやり方です。文字列グローバル変数をWin32/64でうまく管理する記事はこちらに記述します。)にURLの文字列をダイアログの接続ボタンを押した後に受け取るようにします。


 ダイアログにあるテキストエディットボックスと文字列をやり取りするのは以下のような関数を使います。

■SetDlgItemText(hDlg, IDC_URL, pchStrUrl)


■GetDlgItemText(hDlg, IDC_URL, pchStrUrl, (int)sizeof(pchStrUrl));

 

Win32/64 ネットワーク処理開発へ戻る。