読者です 読者をやめる 読者になる 読者になる

GetInterfaceInfo

ネットワークインターフェース情報を取得するには、IPヘルパーAPI(iphlpapi.lib)を使う・・・。
GetInterfaceInfoは、ネットワークインターフェースを取得する・・・。

GetInterfaceInfo function (Windows)

といっても、これはインタフェースの名前とインデックスしか取れない・・・。
(しかも、ipconfigやデバイスマネージャなどで表示されるような名前ではない・・・。てか、どこでみれるんだ・・・。)

f:id:BG1:20170313171131p:plain

コンソールの、

f:id:BG1:20170313171143p:plain

空で、

f:id:BG1:20170313171153p:plain

iphlpapi.libをリンク・・・。

まず、第1引数をNULLにして、GetInterfaceInfoを呼ぶことで、インターフェース情報のサイズをdwOutBufLenに格納させる・・・。

そのあと、newでIP_INTERFACE_INFO構造体の分のメモリを確保し、もう一度GetInterfaceInfoを呼んで取得・・・。

一覧をfor文で出力したら、deleteでメモリを解放・・・。

pIpInterfaceInfo->Adapter[0].Index = 11, pIpInterfaceInfo->Adapter[0].Name = \DE
VICE\TCPIP_{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
続行するには何かキーを押してください . . .

Win7VMで実行したら、数字は伏せたけど、1個だけ出てきた・・・。
しかし、デバイスマネージャみてもipconfigみてもこの名前はないのでよくわからん・・・。

Sample/winapi/GetInterfaceInfo/GetInterfaceInfo/src/GetInterfaceInfo at master · bg1bgst333/Sample · GitHub

CreateRectRgn

これまで、図形を描画するのにRectangleのような描画APIを使ってきた・・・。
他にも楕円を描くEllipseや、多角形を描くPolygonとかがあるが、この図形そのものをハンドルを持つ1つのオブジェクトとして表示する方法もある・・・。
画面上に置けるこの図形のような領域をリージョンという・・・。

CreateRectRgnは、矩形型のリージョンを生成する・・・。

CreateRectRgn 関数

ウィンドウ上に矩形リージョンを表示する・・・。
WM_PAINTで、

CreateRectRgnで、位置(50, 50)でサイズが(300, 200)のリージョンを作成・・・。
このままだと背景が同じ色で見えないので、SelectObjectでhDCが選択しているブラシの色をグレーに変更・・・。
PaintRgnでそのデバイスコンテキストハンドルに設定されたグレーで着色・・・。
SelectObjectで元に戻す・・・。
DeleteObjectでhRgnも削除・・・。

f:id:BG1:20170313152045p:plain

こんな感じでグレーのリージョンが表示された・・・。

Sample/winapi/CreateRectRgn/CreateRectRgn/src/CreateRectRgn at master · bg1bgst333/Sample · GitHub

ユニヴァーサル参照

std::moveの仕様を見ると、

move (utility) - cpprefjp C++日本語リファレンス

"T&& t"という引数の型を見ると、右辺値参照っぽいのになぜ左辺値も引数に取れるのか不思議に思う・・・。
実は、テンプレート関数など、T&&での推論が発生する状況においては、右辺値なら右辺値参照、左辺値なら左辺値参照、という動作をするようになっている・・・。
これをユニヴァーサル参照という・・・。

発生する条件はちょっと複雑で詳しくは、

Universal Reference is 何 - 冬でもスイカバーが食べたい
右辺値参照・ムーブセマンティクス - cpprefjp C++日本語リファレンス

を参照のこと・・・。

とりあえず、右辺値も左辺値も取れるのか試してみる・・・。

funcの定義でT&&で引数を取るようにして、funcに右辺値10と左辺値x(1を代入済み)を渡して呼ぶ・・・。

$ g++ universal_reference.cpp -o universal_reference -std=c++11
$ ./universal_reference
x = 1
val = 10 in func()
val = 100 in func()
val = 1 in func()
val = 100 in func()
x = 100
$

右辺値でも左辺値でもfuncの中で代入できる・・・。
ただ、右辺値の場合は本来一時オブジェクトのものに入れてるので保証しない・・・。

Sample/cpp/universal_reference/universal_reference/src/universal_reference at master · bg1bgst333/Sample · GitHub

WebRequest

Webページを取得する場合など、HTTPリクエストを作成するには、WebRequestを使う・・・。

WebRequest クラス (System.Net)

"http://bgstation0.com"のトップページのHTMLを取得する・・・。

f:id:BG1:20170310181329p:plain

今回は空のプロジェクトで・・・。
(コンソールでもいいんだけど・・・。)

MainClass.csを追加したら、

f:id:BG1:20170310181440p:plain

参照が足りない(というか空だから無い・・・。)ので追加する・・・。

f:id:BG1:20170310181525p:plain

Systemを追加・・・。

でMainClass.csは、

WebRequestはSystem.Net名前空間、Stream系はSystem.IO名前空間なので追加・・・。

response、stream、srはnullをセットしておく・・・。
tryの中で、まずはWebRequest.Createに"http://bgstation0.com"を指定してrequest作成・・・。
今度はrequest.GetResponseでresponseを取得・・・。
responseからresponse.GetResponseStreamでstreamを取得・・・。
しかし、これでは文字列として読み込めないので、StreamReaderのコンストラクタに渡してsrを取得・・・。
sr.ReadToEndでようやく文字列としてstrに格納・・・。
あとは、Console.Writeでstrを出力・・・。

例外が起きたら、catchブロックでex.ToString()で例外内容を出力・・・。

finallyでリソース解放・・・。
reqeustはCloseが無いみたいなので、sr、stream、responseをCloseで閉じる・・・。
(なのでMainブロックに宣言がある・・・。)

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title id="title_index">B.G-STATION</title>
  </head>
  <body id="body_index" bgcolor="#ffffff" text="#7700cc" link="0000ff" alink="ff
0000" vlink="ff00ff">
    <div id="div_titleimage" align="center">
      <img src="http://www.geocities.co.jp/bg_sta/resource/image/title.png" widt
h="460px" height="140px" />
    </div>
    <div id="div_mainmenu" align="center">
      <div id="div_item_sample">
        <a href="sample/index.html">Sample</a>
      </div>
    </div>
  </body>
</html>
続行するには何かキーを押してください . . .

こんな感じで、WebページのHTMLが取得できる・・・。

Sample/dotnet/WebRequest/WebRequest/src/WebRequest_ at master · bg1bgst333/Sample · GitHub

DateTime

日時を取得したい場合は、DateTime構造体を使う・・・。

DateTime 構造体 (System)

DateTime.Nowで現在日時情報が取得できるので、それをTimerで1秒ごとに行い、その都度Labelを更新していくような、簡単な時計を作る・・・。

f:id:BG1:20170310161947p:plain

まず、Labelを選択・・・。

f:id:BG1:20170310162020p:plain

真ん中に配置・・・。

f:id:BG1:20170310162050p:plain

小さいのでFontを調整・・・。

f:id:BG1:20170310162122p:plain

18ぐらいにする・・・。

f:id:BG1:20170310162205p:plain

Timerを追加・・・。

f:id:BG1:20170310162235p:plain

timer1を選択・・・。

f:id:BG1:20170310162312p:plain

Tickイベントのハンドラを生成・・・。

DateTime.NowでDateTime型現在時刻情報を取得できるので、それをDateTime型のdateTimeに格納・・・。
dateTime.ToStringで文字列に変換して、label1.Textに渡す・・・。
その後、timer1.Intervalを1000ミリ秒(1秒)にし、timer1.Enabledをtrueにしてタイマー開始・・・。

timer1_Tickに来るたびに、DateTime.Nowで日時を取得し、dateTime.ToStringで文字列に変換し、label1.Textに反映・・・。

f:id:BG1:20170310163112p:plain

最後にlabel1の位置をやっぱり左に寄せる・・・。(はみ出たので・・・。)

f:id:BG1:20170310162919p:plain

1秒後は、

f:id:BG1:20170310162931p:plain

ということで時計になっている・・・。

Sample/dotnet/DateTime/DateTime/src/DateTime_ at master · bg1bgst333/Sample · GitHub

Timer

Timer(System.Windows.Forms)は、これまでのようなFormウィンドウを持つWinFormsアプリのタイマークラス・・・。

Timer クラス (System.Windows.Forms)

今回は、5秒ごとにメッセージボックスを出す・・・。

f:id:BG1:20170310131733p:plain

メニューをこのように配置して、"開始"クリックと"終了"クリックのハンドラを生成しておく・・・。

f:id:BG1:20170310131903p:plain

Timerをドラッグ・・・。

f:id:BG1:20170310131952p:plain

これも下に追加されるだけ・・・。
timer1を選択し、

f:id:BG1:20170310132110p:plain

プロパティのイベントのTickでタイマーイベント発生時のハンドラを生成・・・。

timer1.Intervalを5000ミリ秒、つまり5秒にセット・・・。

"開始"が押されたら、timer1.Enabledをtrueにしてタイマー開始・・・。

"終了"が押されたら、timer1.Enabledをfalseにしてタイマー停止・・・。

5秒ごとにtimer1_Tickが呼ばれ、中ではMessageBoxで"Timer Event!"と表示している・・・。

f:id:BG1:20170310132656p:plain

"開始"を選択・・・。
5秒経ったら、

f:id:BG1:20170310132725p:plain

"Timer Event!"と出る・・・。
また、5秒経ったら、

f:id:BG1:20170310132753p:plain

"Timer Event!"と出る・・・。
終了するまで繰り返すので、

f:id:BG1:20170310132829p:plain

"終了"を押すと、タイマーが停止して、"Timer Event!"も出なくなる・・・。

Sample/dotnet/Timer/Timer/src/Timer_ at master · bg1bgst333/Sample · GitHub

OpenFileDialog

OpenFileDialogは、"開く"ファイルダイアログのクラス・・・。

OpenFileDialog クラス (System.Windows.Forms)

前回のメニューで"開く"を設置した・・・。
今回は"開く"を押したら、"開く"ファイルダイアログが表示され、ファイルを選択すると、ファイル名(正確にはファイルのフルパス・・・。)がメッセージボックスで表示されるようにする・・・。

f:id:BG1:20170310121901p:plain

メニューアイテム"開く"を設置したら、Clickのハンドラを作成・・・。
で、newでOpenFileDialogを生成してもいいのだが、今回はツールボックスから選択・・・。

f:id:BG1:20170310122000p:plain

Form1にドラッグしても、上には表示されず、下にopenFileDialog1の名前だけ出る・・・。

Form1.csで、

menuItem3_Clickの中で、openFileDialog1.FileNameを空文字""に・・・。
(こうしないと、ファイルダイアログ表示した時に、なぜか"openFileDialog1"が入ってた・・・。)
openFileDialog1.ShowDialogでファイルダイアログを表示・・・。
何かファイルが選択されると、DialogResult.OKが返ってくる・・・。
この時のopenFileDialog1.FileNameをMessageBoxで表示する・・・。

f:id:BG1:20170310122440p:plain

を選択すると、

f:id:BG1:20170310122521p:plain

デフォルトは自分のドキュメントフォルダになるみたい・・・。
ここで、"test.txt"を選択・・・。

f:id:BG1:20170310122632p:plain

ファイル名(フルパス)が表示される・・・。

Sample/dotnet/OpenFileDialog/OpenFileDialog/src/OpenFileDialog_ at master · bg1bgst333/Sample · GitHub