[C++] 223 Visual C++ : ストアアプリのアドオン用ダイアログ作成 FLTK

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

Microsoftストアアプリのアドオンライセンスの有無をチェックし、ライセンスを購入していない場合に購入画面へ案内するダイアログを作成しました。

購入へ誘導するフローのノウハウが全くないので既存アプリのやり方をこれからチェックします。

いきなり購入ボタンを表示するなど、商売っ気を出してユーザーの方を戸惑わせないように気をつけます

#include <FLstd.h>
#include "modalDialog.h"
#include "AddOnDialog.h"
#include "AddOn.h"
#include <DEBUG_MACRO.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>

using std::cout; using std::endl;
using std::string; using std::to_string;
using std::vector;

extern Fl_Double_Window* window;
extern vector<string> labels;
extern vector<string> AddOnLabels;
extern bool AddOn1_bool;

extern modalDialog* dlg;
extern AddOnDialog* AddOndlg;

void AddOn1Check(Fl_Widget*, void*) {
    DEBUG_MACRO(AddOn1_bool,Menu_,);

    if (AddOn1_bool == 0) {
        const char* msg = AddOnLabels[1].c_str();
        AddOndlg = new AddOnDialog(400, 200, AddOnLabels[0].c_str(), msg);
        AddOndlg->hotspot(window);

        int x_win = window->x_root();
        int y_win = window->y_root();
        cout << "x_win " << x_win << " y_win " << y_win << endl;

        AddOndlg->resize(x_win + 205, y_win + 165, 250, 150);
        AddOndlg->set_modal();
        AddOndlg->show();

        return;
    } else {
        const char* msg = AddOnLabels[2].c_str();
        dlg = new modalDialog(400, 200, AddOnLabels[0].c_str(), msg);
        dlg->hotspot(window);

        int x_win = window->x_root();
        int y_win = window->y_root();
        cout << "x_win " << x_win << " y_win " << y_win << endl;

        dlg->resize(x_win + 205, y_win + 165, 250, 150);
        dlg->set_modal();
        dlg->show();
    }
}

[C++] 222 Visual C++ : アプリのウィンドウアイコン設定 FLTK

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

ようやくウィンドウアイコンを設定できました。

new演算子でFl_RGB_Imageオブジェクトを作ることにこだわって遠回りしました。new演算子を使わない書き方でようやく成功しました。

今回のは断続的に2日がかりでしんどかったです。一旦諦めた直後にひらめいてあっさり解決しました。FLTKマスターへの道のりはまだまだ遠いです。

まあ仕様が古いといいますかpngファイルのパスだけでアイコン設定できるようにしないとFLTKのユーザーは増えないでしょうね。

以下の手順になります。

1) アイコンのpngファイルをxpmファイルに変換する。フリーのWEBサービス利用可。
2)xpmファイルをエディタで開き、static char*の変数を適当な名前に変える。
3)xpmファイルをincludeして、main関数を以下のように記述する。

#include "icon16.xpm"

Fl_Double_Window* window;

int main(int argc, char** argv) {
    // ウィンドウアイコン設定
    const Fl_Pixmap icon_pix(icon_xpm16);
    const Fl_RGB_Image icon_rgb(&icon_pix);
        
    window = new Fl_Double_Window(50, 50, 660, 480, "COLOR SAMPLE JP");
    window->color(fl_rgb_color(238, 238, 238));
    window->icon(&icon_rgb);

    <以下略>
}
static char *icon_xpm16[] = {
/* columns rows colors chars-per-pixel */
"16 16 14 1 ",
"  c #180614",
". c #006E54",
"X c #016F55",
"o c #ED6D3D",
"O c #EE6D3D",
"+ c #30A36A",
"@ c #3EB370",
"# c #409370",
"$ c #4C9A76",
"% c #1E50A2",
"& c #75B188",
"* c #DAB683",
"= c #CEE4AE",
"- c None",
/* pixels */
"----------------",
"----------------",
"--==  ===....=--",
"--=   ==.+@@@.--",
"--     =.@@@@.--",
"--     =.@@@@.--",
"--==    #.@@XX--",
"--==== ==&..$=--",
"--=Ooo===%====--",
"--ooooo=%%%%==--",
"--oooooo=%%%%%--",
"--oooooo=%%%%%--",
"--ooooo*==%%%=--",
"--=oooo===%%==--",
"----------------",
"----------------"
};

[C++] 221 Visual C++ : 非IDE開発環境 その5 アプリMakefile Debug, Release

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

カラーアプリのMakefileをDebugモード、Releaseモードで実行できるようにしました。

# コンパイラ設定他
COMPILER = cl
DEBUG = /D "_DEBUG"
# DEBUG = 
CONSOLE = /SUBSYSTEM:CONSOLE
WINDOWS = /SUBSYSTEM:WINDOWS
LINKER = LINK
RESOURCE = "D:\code\VC++\Projects\ColorSampleJP\images\ColorSampleJP.res"

# オプション設定
CPPFLAGS = /std:c++17 /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl  /Zc:inline /fp:precise /D "_UNICODE" \
/errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /c /diagnostics:column /EHsc
LDFLAGS = /MACHINE:X64

# includeパス(-I)
INCLUDE = /I"C:\packages\fltk-1.3.8\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\cppwinrt" \
/I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um" \
/I"D:\code\VC++\Projects\ColorSampleJP\include" \
/I"D:\code\VC++\Projects\ColorConvert\ColorConvert" \
/I"D:\code\VC++\Projects\Split\Split" \
/I"D:\code\VC++\mylib_vc\include" \
/I"D:\code\VC++\Projects\ColorSampleJP\images"

# ライブラリ(-l)
LIBRARY_l = /DYNAMICBASE "wsock32.lib" "comctl32.lib" \
"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" \
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" \
"uuid.lib" "odbc32.lib" "odbccp32.lib" \
"CharExtract.lib" "Funcs.lib" "ColorConvert.lib" "Split.lib"

LIBRARY_l_Debug = "fltkd.lib" "fltk_jpegd.lib" "fltk_imagesd.lib"
LIBRARY_l_Release = "fltk.lib" "fltk_jpeg.lib" "fltk_images.lib"

# ライブラリパス(-L)
LIBRARY_L = /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" \
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" \
/LIBPATH:"D:\code\VC++\mylib_vc\lib"

LIBRARY_L_Debug = /LIBPATH:"C:\packages\fltk-1.3.8\lib\Debug" \
/LIBPATH:"D:\code\VC++\Projects\ColorConvert\x64\Debug" \
/LIBPATH:"D:\code\VC++\Projects\Split\x64\Debug"
LIBRARY_L_Release = /LIBPATH:"C:\packages\fltk-1.3.8\lib\Release" \
/LIBPATH:"D:\code\VC++\Projects\ColorConvert\x64\Release" \
/LIBPATH:"D:\code\VC++\Projects\Split\x64\Release"

# ソースファイル
SRCDIR = .\src
SRCS = $(SRCDIR)\btnAction.cpp $(SRCDIR)\FileChooser.cpp $(SRCDIR)\FileChooser2.cpp $(SRCDIR)\main.cpp \
$(SRCDIR)\modalDialog.cpp $(SRCDIR)\searchLocation.cpp $(SRCDIR)\csvProcessChar.cpp

# オブジェクトファイル
OBJDIR = .\obj
OBJS = $(OBJDIR)\btnAction.obj $(OBJDIR)\FileChooser.obj $(OBJDIR)\FileChooser2.obj $(OBJDIR)\main.obj \
$(OBJDIR)\modalDialog.obj $(OBJDIR)\searchLocation.obj $(OBJDIR)\csvProcessChar.obj

# 実行ファイル
TARGETDIR = .\bin
TARGET = ColorSampleJP.exe

# cppファイルからoファイル作成 $<:依存ファイル
$(OBJDIR)\btnAction.obj: $(SRCDIR)\btnAction.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move btnAction.obj $(OBJDIR) >nul

$(OBJDIR)\FileChooser.obj: $(SRCDIR)\FileChooser.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move FileChooser.obj $(OBJDIR) >nul

$(OBJDIR)\FileChooser2.obj: $(SRCDIR)\FileChooser2.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move FileChooser2.obj $(OBJDIR) >nul

$(OBJDIR)\main.obj: $(SRCDIR)\main.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move main.obj $(OBJDIR) >nul

$(OBJDIR)\modalDialog.obj: $(SRCDIR)\modalDialog.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move modalDialog.obj $(OBJDIR) >nul

$(OBJDIR)\searchLocation.obj: $(SRCDIR)\searchLocation.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move searchLocation.obj $(OBJDIR) >nul

$(OBJDIR)\csvProcessChar.obj: $(SRCDIR)\csvProcessChar.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(INCLUDE) $<
	move csvProcessChar.obj $(OBJDIR) >nul

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(LINKER) $(CONSOLE) $(LIBRARY_l) $(LIBRARY_l_Debug) $(LIBRARY_L) $(LIBRARY_L_Debug) $(OBJS) $(LDFLAGS) $(RESOURCE)
	rename btnAction.exe $(TARGET)
	move $(TARGET) $(TARGETDIR) >nul

# Releaseモード
# $(TARGET):$(OBJS)
# 	$(LINKER) $(WINDOWS) $(LIBRARY_l) $(LIBRARY_l_Release) $(LIBRARY_L) $(LIBRARY_L_Release) $(OBJS) $(LDFLAGS) $(RESOURCE)
# 	rename btnAction.exe $(TARGET)
# 	move $(TARGET) $(TARGETDIR) >nul

# ビルド
.PHONY:all
all: clean $(TARGET)

# ファイル削除
.PHONY:clean
clean:
	del /Q $(TARGET) $(OBJS) vc140.idb vc140.pdb

[C++] 220 Visual C++ : 非IDE開発環境 その4 アプリアイコン設定

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

アプリアイコンはMakefileのリンク時のオプションとしてresファイルを入れておけば埋め込まれます。

resファイルはVisual Studioプロジェクトのリソースファイルとしてicoファイルを登録するとビルド時に自動生成します。今回は自製せずにこちらを流用しました。

# コンパイラ設定他
COMPILER = cl
DEBUG = /D "_DEBUG"
CONSOLE = /D "_CONSOLE"
LINKER = LINK
RESOURCE = "D:\code\VC++\Projects\ColorSampleJP\images\ColorSampleJP.res"

<中略>

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(LINKER) $(LIBRARY_l) $(LIBRARY_L) $(OBJS) $(LDFLAGS) $(RESOURCE) 
	rename btnAction.exe $(TARGET)
	move $(TARGET) $(TARGETDIR) >nul

[C++] 219 Visual C++ : 非IDE開発環境 その3 アプリMakefile作成

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

カラーアプリのMakefileを作成しました。

やはりGNU MakeはVisual C++では思うように動いてくれません。挙動のおかしなところはMakefile内でつじつまを合わせています。Windows純正のNMAKEを使う方が良さそうです。

プロジェクトディレクトリのサイズは18MBですからVisual Studio版1.51GBの80分の1になりました。ヘッダファイルとcppファイルを別ディレクトリに分離しているのでアクセス性も高いです。

128GBや256GBなどストレージの小さなWindowsPCを使用しているプログラマにおすすめの開発環境です。私のPCはcドライブ512GB、dドライブ2TBですが、それでもプロジェクトのサイズは看過できませんでしたね。

これでいらだちも収まり、良い心持ちでプログラミングできそうです。

# コンパイラ設定他
COMPILER = cl
DEBUG = /D "_DEBUG"
CONSOLE = /D "_CONSOLE"
LINKER = LINK

# オプション設定
CPPFLAGS = /std:c++17 /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl  /Zc:inline /fp:precise /D "_UNICODE" \
/errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /c /diagnostics:column /EHsc
LDFLAGS = 

# includeパス(-I)
INCLUDE = /I"C:\packages\fltk-1.3.8\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\cppwinrt" \
/I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um" \
/I"D:\code\VC++\Projects\ColorSampleJP\include" \
/I"D:\code\VC++\Projects\ColorConvert\ColorConvert" \
/I"D:\code\VC++\Projects\Split\Split" \
/I"D:\code\VC++\mylib_vc\include"

# ライブラリ(-l)
LIBRARY_l = /DYNAMICBASE "fltkd.lib" "wsock32.lib" "comctl32.lib" "fltk_jpegd.lib" \
"fltk_imagesd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" \
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" \
"uuid.lib" "odbc32.lib" "odbccp32.lib" \
"CharExtract.lib" "Funcs.lib" "ColorConvert.lib" "Split.lib"

# ライブラリパス(-L)
LIBRARY_L = /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" \
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" \
/LIBPATH:"C:\packages\fltk-1.3.8\lib\Debug" \
/LIBPATH:"D:\code\VC++\Projects\ColorConvert\x64\Debug" \
/LIBPATH:"D:\code\VC++\Projects\Split\x64\Debug" \
/LIBPATH:"D:\code\VC++\mylib_vc\lib"

# ソースファイル
SRCDIR = .\src
SRCS = $(SRCDIR)\btnAction.cpp $(SRCDIR)\FileChooser.cpp $(SRCDIR)\FileChooser2.cpp $(SRCDIR)\main.cpp \
$(SRCDIR)\modalDialog.cpp $(SRCDIR)\searchLocation.cpp $(SRCDIR)\csvProcessChar.cpp

# オブジェクトファイル
OBJDIR = .\obj
OBJS = $(OBJDIR)\btnAction.obj $(OBJDIR)\FileChooser.obj $(OBJDIR)\FileChooser2.obj $(OBJDIR)\main.obj \
$(OBJDIR)\modalDialog.obj $(OBJDIR)\searchLocation.obj $(OBJDIR)\csvProcessChar.obj

# 実行ファイル
TARGETDIR = .\bin
TARGET = ColorSampleJP.exe

# cppファイルからoファイル作成 $<:依存ファイル
$(OBJDIR)\btnAction.obj: $(SRCDIR)\btnAction.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move btnAction.obj $(OBJDIR) >nul

$(OBJDIR)\FileChooser.obj: $(SRCDIR)\FileChooser.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move FileChooser.obj $(OBJDIR) >nul

$(OBJDIR)\FileChooser2.obj: $(SRCDIR)\FileChooser2.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move FileChooser2.obj $(OBJDIR) >nul

$(OBJDIR)\main.obj: $(SRCDIR)\main.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move main.obj $(OBJDIR) >nul

$(OBJDIR)\modalDialog.obj: $(SRCDIR)\modalDialog.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move modalDialog.obj $(OBJDIR) >nul

$(OBJDIR)\searchLocation.obj: $(SRCDIR)\searchLocation.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move searchLocation.obj $(OBJDIR) >nul

$(OBJDIR)\csvProcessChar.obj: $(SRCDIR)\csvProcessChar.cpp
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<
	move csvProcessChar.obj $(OBJDIR) >nul

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(LINKER) $(LIBRARY_l) $(LIBRARY_L) $(LDFLAGS) $(OBJS)
	rename btnAction.exe $(TARGET)
	move $(TARGET) $(TARGETDIR) >nul

# ビルド
.PHONY:all
all: clean $(TARGET)

# ファイル削除
.PHONY:clean
clean:
	del /Q $(TARGET) $(OBJS) vc140.idb vc140.pdb

[C++] 218 Visual C++ : 非IDE開発環境 その2 Makefile作成

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

MakefileをGNU Makeで作成しました。WindowsにはNMAKEという同種のコマンドがあるようです。

GNU Makeはコマンドプロンプトの文字コードをUTF-8にしても何故か文字化けのままです。

# コンパイラ設定他
COMPILER = cl
DEBUG = /D "_DEBUG"
CONSOLE = /D "_CONSOLE"
LINKER = LINK

# オプション設定
CPPFLAGS = /std:c++17 /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl  /Zc:inline /fp:precise /D "_UNICODE" \
/errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /c /diagnostics:column
LDFLAGS = 

# includeパス(-I)
INCLUDE = /I"C:\packages\fltk-1.3.8\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include" \
/I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt" \
/I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\cppwinrt" \
/I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um"

# ライブラリ(-l)
LIBRARY_l = /DYNAMICBASE "fltkd.lib" "wsock32.lib" "comctl32.lib" "fltk_jpegd.lib" \
"fltk_imagesd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" \
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" \
"uuid.lib" "odbc32.lib" "odbccp32.lib"

# ライブラリパス(-L)
LIBRARY_L = /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" \
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" \
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" \
/LIBPATH:"C:\packages\fltk-1.3.8\lib\Debug"

# ソースファイル
SRCDIR = 
SRCS = test.cpp

# オブジェクトファイル
OBJDIR = 
OBJS = test.obj

# 実行ファイル
TARGETDIR = 
TARGET = test.exe

# cppファイルからoファイル作成 $<:依存ファイル
$(OBJS): $(SRCS)
	$(COMPILER) $(CPPFLAGS) $(DEBUG) $(CONSOLE) $(INCLUDE) $<

# oファイルから実行ファイル作成
$(TARGET):$(OBJS)
	$(LINKER) $(LIBRARY_l) $(LIBRARY_L) $(LDFLAGS) $(OBJS)

# ビルド
.PHONY:all
all: clean $(TARGET)

# ファイル削除
.PHONY:clean
clean:
	del /Q $(TARGET) $(OBJS) vc140.idb vc140.pdb

[C++] 217 Visual C++ : 非IDE開発環境 その1 Makefile作成準備

[Windows11, Visual C++2017, FLTK 1.3.8, NO IDE]

これまで我慢してVisual Studioを使ってきましたが、製作中アプリのプロジェクトディレクトリのサイズが1.5GB越えと知り(MinGWはたった6MB)、脱Visual Studio(GUI)の決意を固めました。

動作が重いなどパフォーマンスは低いのにストレージをドカ食いはあり得ないです。

Makefileでコンソール開発環境の構築を図ります。とりあえずFLTKを使ったプログラムをコンソールでビルドしました。

このコマンドを元にMakefileを作成します。

#include<FL/Fl.h>
#include<FL/Fl_Box.h>
#include<FL/Fl_Window.h>

Fl_Window* window;
Fl_Box* box;

int main()
{
	window = new Fl_Window(200, 200, 200, 200, "Window title");
	box = new Fl_Box(0, 0, 200, 200, "Hey, I mean, Hello, World!");

	window->show();
	return Fl::run();
}
cl /std:c++17 ^
/GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl  /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" ^
/errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /diagnostics:column ^
/I"C:\packages\fltk-1.3.8\include" ^
/DYNAMICBASE "fltkd.lib" "wsock32.lib" "comctl32.lib" "fltk_jpegd.lib" "fltk_imagesd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" ^
"D:\code\VC++\Projects\test_fltk\test.cpp" /link /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" /LIBPATH:"C:\packages\fltk-1.3.8\lib\Debug" 

オブジェクトファイル作成、実行ファイル作成に分ける場合は

cl /std:c++17 ^
/GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl  /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" ^
/errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /c /diagnostics:column ^
/I"C:\packages\fltk-1.3.8\include" ^
"D:\code\VC++\Projects\test_fltk\test.cpp"
link ^
/DYNAMICBASE "fltkd.lib" "wsock32.lib" "comctl32.lib" "fltk_jpegd.lib" "fltk_imagesd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" ^
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64" ^
/LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64" ^
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" ^
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64" ^
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22000.0\\um\x64" ^
/LIBPATH:"C:\packages\fltk-1.3.8\lib\Debug" ^
"D:\code\VC++\Projects\test_fltk\test.obj"

[C++] 216 Visual C++ : アドオン作成 その3アドオンライセンスの確認

[Windows11, Visual C++2017, FLTK 1.3.8, Visual Studio 2022]

アプリの起動時にアドオンライセンスの有無を確認できるようにしました。

たった十数行のために丸一日費やしました。C#のコード例がほとんどでC++で書くのはキツいものがあります。ドキュメントも読みにくく情報が散らばっていて体系的に理解するのに苦労します。

これではC++を使ってMicrosoftストアアプリで収益を得ようとは思わないでしょう。まあそれ以前にストア自体閑古鳥が鳴いていますが。かなりの方々が実装途中で脱落したのではないでしょうか。私も完成させる自信はありませんが、やれるところまでやってみます。

ちなみにC#への移植は全く考えていません。Microsoftと関わるのはVC++までです。

ところでプロジェクトのサイズを比較してみるとMinGW版が6MBに対し、VC++版が1.5GB、パッケージプロジェクトを追加すると1.8GBです。やろうとしていることは一緒なのにストレージはバカ食いで、IDEは重く、コードは書きにくい、の三重苦です。ますますM社が嫌いになりました。

やはりC++の快適なプログラミングはMakefileを自作して、コンソールでビルドするに限ります。スキルを磨けば、時間やストレージを浪費しなくて済みます。

#include <DEBUG_MACRO.h> // coutデバッグマクロ
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>

using namespace winrt;
using namespace winrt::Windows::Services::Store;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;

bool AddOn1_bool;

int main(int argc, char** argv) {
    // StoreContext取得
    StoreContext _storeContext = StoreContext::GetDefault();

    // StoreAppLicenseを完了時に結果を返す非同期操作にて取得
    IAsyncOperation<StoreAppLicense> _storeAppLicense = _storeContext.GetAppLicenseAsync();
    StoreAppLicense _storeAppLicense2 = _storeAppLicense.get();

    // アドオンライセンス情報を取得
    IMapView<hstring, StoreLicense> addon_lisences = _storeAppLicense2.AddOnLicenses();

    // IDからbool値を取得
    AddOn1_bool = addon_lisences.HasKey(L"ID");
    DEBUG_MACRO(AddOn1_bool,Start_,);
    <以下略>
}
Start_AddOn1_bool : 0

[C++] 215 Visual C++ : アドオン作成 その2 公式ドキュメント

[Windows11, Visual C++2017, FLTK 1.3.8, Visual Studio 2022]

カラーアプリのアドオン実装に際し、その仕組を理解するため公式ドキュメントを調べています。

Microsoftの公式ドキュメントは日本語の体を成していながら何故か頭に入ってこないので理解するまで何度も読むようにします。

アプリ内購入の実装
Windows.Services.Store 名前空間を使用して、アプリでアプリ内購入をユーザーに提供するには:
1.ユーザーが購入できるアドオンをアプリで提供する場合、パートナー センターで、アプリに関するアドオンの申請を作成します。
2.アプリで提供されるアプリやアドオンの製品情報を取得してから、ライセンスがアクティブになっているかどうかを判断する (つまり、アプリやアドオンを使用するためのライセンスをユーザーが所有しているかどうかを判断する) ようにアプリのコードを記述します。 ライセンスがアクティブになっていない場合、ユーザーに販売するためのアプリやアドオンをアプリ内購入として提供する UI を表示します。
3.ユーザーがアプリやアドオンの購入を選んだ場合、製品を購入するための適切なメソッドを使用します。
・ユーザーがアプリや永続的なアドオンを購入する場合は、「アプリとアドオンのアプリ内購入の有効化」の指示に従ってください。
・ユーザーがコンシューマブルなアドオンを購入する場合は、「コンシューマブルなアドオン購入の有効化」指示に従ってください。
・ユーザーがサブスクリプション アドオンを購入する場合は、「アプリのサブスクリプション アドオンの有効化」の指示に従ってください。
4.この記事に記載されているテスト ガイダンスに従って、実装をテストします。

Microsoft アプリ内購入と試用版

Windows.Services.Store 名前空間

クラス

StoreAcquireLicenseResult現在のアプリのダウンロード コンテンツ (DLC) アドオン パッケージのライセンスを取得する要求の応答データを提供します。
StoreAppLicenseアプリによって提供される製品のライセンスなど、現在のアプリのライセンス情報を提供します。
StoreAvailability購入できる製品 SKU の特定のインスタンスを表します。
StoreCanAcquireLicenseResultダウンロードコンテンツ (DLC) アドオン パッケージのライセンスを取得できるかどうかを判断する要求の応答データを提供します。
StoreCollectionDataユーザーが使用する権利を持つ製品 SKU の追加データを提供します。
StoreConsumableResult現在のアプリの消耗品アドオンを含む要求の応答データを提供します。
StoreContext現在のアプリの Microsoft Store 関連データにアクセスして管理するために使用できるメンバーを提供します。 たとえば、このクラスのメンバーを使用して、現在のアプリの Microsoft Store 登録情報とライセンス情報を取得したり、アプリによって提供されている現在のアプリまたは製品を購入したり、アプリのパッケージ更新プログラムをダウンロードしてインストールしたりできます。デスクトップ アプリでは、UI を表示する方法でこのクラスのインスタンスを使用する前に、オブジェクトをその所有者のウィンドウ ハンドルに関連付ける必要があります。 詳細およびコード例については、「 CoreWindow に依存する WinRT UI オブジェクトの表示」を参照してください。
StoreImageWindows ストアの製品一覧に関連付けられているイメージを表します。
StoreLicense現在のアプリに関連付けられている永続的なアドオンのライセンス情報を提供します。
StorePackageInstallOptionsRequestDownloadAndInstallStorePackagesAsync メソッドを使用して、現在のアプリのダウンロード可能なコンテンツ (DLC) パッケージをダウンロードしてインストールするときに指定できるオプションを表します。
StorePackageLicense現在のアプリのダウンロードコンテンツ (DLC) パッケージのライセンス情報を提供します。
StorePackageUpdateMicrosoft Store からダウンロードできる更新プログラムがある現在のアプリのパッケージに関する情報を提供します。
StorePackageUpdateResult現在のアプリのパッケージをダウンロードしてインストールする要求の応答データを提供します。
StorePriceMicrosoft Store の製品登録情報の価格情報が含まれています。
StoreProductMicrosoft Store で利用可能な製品を表します。
StoreProductOptionsGetStoreProductsAsync メソッドと共に使用して、現在のアプリに関連付けられている指定された製品の情報を取得できるフィルター文字列のコレクションが含まれています。
StoreProductPagedQueryResult現在のアプリ内から購入できる製品に関する詳細を取得する、ページングされた要求の応答データを提供します。
StoreProductQueryResult現在のアプリ内から購入できる製品に関する詳細を取得する要求の応答データを提供します。
StoreProductResult現在のアプリに関する詳細を取得する要求の応答データを提供します。
StorePurchaseProperties購入時にユーザーに表示する製品名など、製品の購入要求に渡すことができる追加の詳細が含まれます。
StorePurchaseResultアプリによって提供されるアプリまたは製品を購入する要求の応答データを提供します。
StoreQueueItem現在のアプリのダウンロードおよびインストール キューにある新規または更新されたパッケージに関する情報を表します。
StoreQueueItemCompletedEventArgsStoreQueueItem クラスの Completed イベントのデータを提供します。
StoreQueueItemStatus現在のアプリのダウンロードおよびインストール キューにある新しいパッケージまたは更新されたパッケージの状態情報を提供します。
StoreRateAndReviewResult製品の評価とレビューを行う要求の応答データを提供します。
StoreRequestHelperWindows SDK で対応する API をまだ使用できない操作のために Microsoft Store に要求を送信するために使用できるヘルパー メソッドを提供します。
StoreSendRequestResultMicrosoft Store に送信される要求の応答データを提供します。
StoreSkuMicrosoft Store の製品の在庫保管単位 (SKU) に関する情報を提供します。
StoreSubscriptionInfo定期請求があるサブスクリプションを表す製品 SKU のサブスクリプション情報を提供します。
StoreUninstallStorePackageResult現在のアプリのパッケージをアンインストールする要求の応答データを提供します。
StoreVideoMicrosoft Store の製品登録情報に関連付けられているビデオを表します。

構造体

StorePackageUpdateStatusダウンロードまたはインストール要求に関連付けられているパッケージの状態情報を提供します。

列挙型

StoreCanLicenseStatusダウンロード コンテンツ (DLC) アドオン パッケージのライセンス状態を表す値を定義します。
StoreConsumableStatusコンシューマブル アドオンに関連する要求の状態を表す値を定義します。
StoreDurationUnitサブスクリプションの試用期間または請求期間の単位を表す値を定義します。
StorePackageUpdateStateパッケージのダウンロードまたはインストール要求の状態を表す値を定義します。
StorePurchaseStatusアプリまたはアドオンを購入する要求の状態を表す値を定義します。
StoreQueueItemExtendedState現在のアプリのダウンロードおよびインストール キューにある新規または更新されたパッケージの拡張状態情報を表す値を定義します。
StoreQueueItemKindダウンロードおよびインストール キューで現在のパッケージに対して実行される操作を記述する値を定義します。
StoreQueueItemState現在のアプリのダウンロードおよびインストール キューにある新しいパッケージまたは更新されたパッケージの状態を指定する値を定義します。
StoreRateAndReviewStatus製品のレートとレビュー要求の結果の状態を取得します。
StoreUninstallStorePackageStatusパッケージアンインストール要求の状態を表す値を定義します。

[C++] 214 Visual C++ : アドオン作成 その1

[Windows11, Visual C++2017, FLTK 1.3.8, Visual Studio 2022]

カラーアプリのアドオンを作成します。

まず前回記事で一度断念したWindows Application パッケージプロジェクトを作成しました。

図を見てもわかるようにアプリのプロジェクトとソリューション内で共存する形になります。

パッケージプロジェクトを右クリックしビルドを選択すると、プロジェクトとパッケージプロジェクトの両方でビルドします。

パッケージプロジェクト内のPackage.appxmanifestをダブルクリックし、マニフェストデザイナーでパッケージの構成を設定します。

次にUWPのAPIを使うため、パッケージマネージャーコンソールから以下コマンドでMicrosoft.Windows.CppWinRT NuGet パッケージをインストールします。

NuGet\Install-Package Microsoft.Windows.CppWinRT -Version 2.0.221121.5

あとはWindows.Services.Store APIを呼び出して、アドオンを作成します。

  • Windows.Services.Store.StoreAcquireLicenseResult
  • Windows.Services.Store.StoreAppLicense
  • Windows.Services.Store.StoreAvailability
  • Windows.Services.Store.StoreCollectionData
  • Windows.Services.Store.StoreConsumableResult
  • Windows.Services.Store.StoreContext
  • Windows.Services.Store.StoreImage
  • Windows.Services.Store.StoreLicense
  • Windows.Services.Store.StorePackageLicense
  • Windows.Services.Store.StorePackageUpdate
  • Windows.Services.Store.StorePackageUpdateResult
  • Windows.Services.Store.StorePrice
  • Windows.Services.Store.StoreProduct
  • Windows.Services.Store.StoreProductPagedQueryResult
  • Windows.Services.Store.StoreProductQueryResult
  • Windows.Services.Store.StoreProductResult
  • Windows.Services.Store.StorePurchaseProperties
  • Windows.Services.Store.StorePurchaseResult
  • Windows.Services.Store.StoreRequestHelper
  • Windows.Services.Store.StoreSendRequestResult
  • Windows.Services.Store.StoreSku
  • Windows.Services.Store.StoreVideo