IShellLink

これまでは、COMサーバを作る側で紹介してきたが、ここからはCOMクライアントとして呼ぶ側として紹介していく。

IShellLinkは、ショートカットを作成したり、ショートカットのリンク先情報を取得する時などに使う。

IShellLinkA | Microsoft Docs
ショートカットの作成
COMを使用してショートカットのリンク先を取得する(32/64bit)

コンソール
コンソール

コンソールで作成。

空のプロジェクト
空のプロジェクト

コンソールの空のプロジェクト。

新しい項目
新しい項目

新しい項目として、

IShellLink.cpp
IShellLink.cpp

IShellLink.cppを追加。

CoCreateInstanceで、IShellLinkポインタpShellLinkとして取得できるので、成功ならポインタを出力。

pShellLink success!, pShellLink = 0x006015d0
続行するには何かキーを押してください . . .

こんな感じ。

ブレークポイント
ブレークポイント

ブレークポイント置いて、オブジェクトの中を見てみる。

取得前
取得前

取得前はこうなっている。

取得後
取得後

取得後はこう。

結局は、メソッド呼んで、何かしらの処理をし、結果をもらわないと何もわからない。

Sample/com/IShellLink/IShellLink/src/IShellLink at master · bg1bgst333/Sample · GitHub

CWindowImpl

ATLで、ウィンドウを作成し、表示するには、CWindowImplが必要。

CWindowImpl クラス | Microsoft Docs
ATL/WTLプログラミング 1:ATL/WTLの概要と基本 (1/2):CodeZine(コードジン)

ちょっと使い方が独特。

まず、

コンソール
コンソール

コンソールでプロジェクト作成。

コンソールの空のプロジェクト
コンソールの空のプロジェクト

コンソールの空のプロジェクト。

空のプロジェクト
空のプロジェクト

空の状態。

新しい項目
新しい項目

新しい項目を追加。

stdafx.h
stdafx.h

stdafx.hを追加。

必要なインクルードや、CComModule。

プロパティ
プロパティ

プロパティで、

静的にリンク
静的にリンク

[ATLに静的にリンク]に変更。

新しい項目
新しい項目

今度は、

CustomWindow.h
CustomWindow.h

CustomWindow.hを追加。

CWindowImplのテンプレート引数をCCustomWindowとしたクラスの派生クラスとしてCCustomWindowを定義する。
DECLARE_WND_CLASSマクロでウィンドウクラス名を登録できる。
メッセーマップもわかりやすい。
ここではOnDestroyでメッセージループ終了処理だけ実装。

新しい項目
新しい項目

また追加。

WinMain.cpp
WinMain.cpp

WinMain.cppだ。

CCustomWindowオブジェクトを作成して、customWnd.Createでウィンドウ作成、customWnd.ShowWindowでウィンドウ表示。
そのあと、メッセージループ処理。

で、これでビルドすると、

ビルドエラー
ビルドエラー

コンソールじゃダメなのでは・・・。

Visual Studioアプリケーションの種類を変更する方法

やっぱり・・・。

サブシステム
サブシステム

[サブシステム]を[コンソール]から[Windows]へ。

プリプロセッサ
プリプロセッサ

[プリプロセッサ]も[_CONSOLE]を、

_WINDOWS
_WINDOWS

[_WINDOWS]に。

ビルド成功
ビルド成功

これでビルドできたので、実行すると、

ウィンドウ表示
ウィンドウ表示

ウィンドウが表示される。

やっぱり、"コンソールアプリケーション"の空のプロジェクトではなく、"Win32プロジェクト"の空のプロジェクトで、"プロジェクト完成後"に、"ATLに静的にリンク"の状態にする。
このプロジェクトの作成の部分が、前回間違ってたので、今回が正しい・・・。

Sample/atl/CWindowImpl/CWindowImpl/src/CWindowImpl at master · bg1bgst333/Sample · GitHub

CDocManager

CDocManagerは、ドキュメントテンプレートを管理しているようだが、どういう役割をしているか詳細はこれから調べていく。

MFC Document/View documentation and enhancements - CodeProject

しかも、インターナルクラスなのか、MSDNやdocsのリファレンスにはなく、MFC階層図にも無い模様。

MFCアプリケーション
MFCアプリケーション

MFCで。
この先は、前回と変わらない。

ドキュメントテンプレート文字列
ドキュメントテンプレート文字列

こんなドキュメントテンプレート文字列。

生成されたクラス
生成されたクラス

今回、またCViewに戻してる。

AddDocTemplate
AddDocTemplate

AddDocTemplateにブレークポイントおいて、ここでステップイン。

CWinApp::AddDocTemplate
CWinApp::AddDocTemplate

CWinApp::AddDocTemplateはこうなっている。
ここでCDocManagerをnewして、m_pDocManagerに格納する。

new CDocManager
new CDocManager

ここでステップインすると、

new
new

ここにきちゃうので、いったんステップアウト。

もう一回
もう一回

もう一回ステップイン。

なにもない
なにもない

なんとコンストラクタなにもない。

m_pDocManagerはどうなっているのか
m_pDocManagerはどうなっているのか

ステップオーバーしてm_pDocManagerの中身はどうなっているのか見てみると、

m_pDocManagerの中身
m_pDocManagerの中身

m_templateListやpStaticListというリストがある。
ドキュメントテンプレートを保持しておくリストのようだ。

今回はここまで。

Sample/mfc/CDocManager/CDocManager/src/CDocManager at master · bg1bgst333/Sample · GitHub

DestroyWindow

DestroyWindowは、指定されたウィンドウハンドルのウィンドウを破棄する。

DestroyWindow function | Microsoft Docs

空のプロジェクトから、メニューリソースを追加して、

DestroyWindow.rcはこのようにアイテム1つだけのメニューとする。

resource.hは、

メニューとアイテムに加えてボタン用リソースIDも用意。

DestroyWindow.cppで、

ID_ITEM_1_1を選択した時も、ID_BUTTON1を押した時も、DestroyWindowでhwndが指すウィンドウを破棄する。

実行時
実行時

実行するとこうだが、

Item1-1
Item1-1

Item1-1を選択すると、ウィンドウは閉じる(実際は破棄されている)し、

Button1
Button1

Button1を押しても、ウィンドウは閉じる。(実際は破棄されている。)

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

link

linkは、ファイルのハードリンクを作成するのに使う。

シンボリックリンクとハードリンクの違い - Qiita
シンボリックリンクの使い方と落とし穴 - Qiita
Manpage of LINK
ファイルの別名を作成する(ハード・リンク) | C言語入門講座

link.cで、

"test1/test1.txt"をリンク先として、"test1_hlnk"というハードリンクを作成。
ハードリンクは元のファイルと同じiノードを指すので、ファイルが移動しても削除されても、それらの情報はiノードに反映される。

$ mkdir test1
$ cd test1/
$ vi test1.txt
$ cat test1.txt 
ABCDE
$

test1ディレクトリの下にtest1.txtを作成し、"ABCDE"という内容にする。
上のディレクトリに戻って、

$ vi link.c 
$ gcc link.c -o link
$ ls
link  link.c  test1
$ ./link
create test1_hlnk success!
$ ls
link  link.c  test1  test1_hlnk
$

link.cを作成し、上記のプログラムを書いた後、コンパイルして、実行すると、test1_hlnkが作成される。

$ ls -li
合計 24
3934494 -rwxrwxr-x. 1 bg1 bg1 8728  1月 11 13:06 link
3934496 -rw-rw-r--. 1 bg1 bg1  787  1月 11 13:05 link.c
4066613 drwxrwxr-x. 2 bg1 bg1 4096  1月 11 12:51 test1
4066615 -rw-rw-r--. 2 bg1 bg1    6  1月 11 12:51 test1_hlnk
$ ls -li test1
合計 4
4066615 -rw-rw-r--. 2 bg1 bg1 6  1月 11 12:51 test1.txt
$ 

test1_hlnkとtest1/test1.txtのiノード番号が一緒。
なので、

$ vi test1_hlnk 
$ cat test1_hlnk 
ABCDE
XYZ
$ cat test1/test1.txt 
ABCDE
XYZ
$

このように変更が反映されるし、

$ mkdir test2
$ mv test1/test1.txt test2
$ ls test1
$ ls test2
test1.txt
$ cat test1_hlnk 
ABCDE
XYZ
$ cat test2/test1.txt 
ABCDE
XYZ
$

test2ディレクトリを作成して、test1/test1.txtをtest2の下に移動しても、test1_hlnkでtest2/test1.txtにアクセスできる。

Sample/unixsyscall/link/link/src/link at master · bg1bgst333/Sample · GitHub

cout

coutは、出力演算子で標準出力に出力するために指定する標準出力ストリームオブジェクトである。

cout - cpprefjp C++日本語リファレンス
std::cout, std::wcout - cppreference.com

std::coutは、グローバルオブジェクトなので、グローバルなクラスや構造体の定義内でも、iostreamのインクルードがそれ以前にされていれば、使う事が出来る。


$ vi cout.cpp
$ g++ cout.cpp -o cout
$ ./cout 
ctor
main
dtor
$

st生成前にcoutの準備は出来ている。

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

新年のご挨拶2019

あけましておめでとうございます。
2019年もよろしくお願いいたします。

今日は、狭山不動尊に初詣に行きました。

おみくじが大吉だったので、今年はいろいろいいことがあればいいのですが。

まずは就職できるようにですね・・・。

また、メットライフドームの横に建設中の施設がいくつかありました。

www.seibulions.jp

正面左手は新しいストア、正面右手奥は新しい球団本部、そしてところざわサクラタウン並みに大きい正面右手前の建物は若獅子寮兼室内練習場のようですね。
完成が楽しみですね。

以上です。