(1)関数テンプレートを利用してint/std::string型の配列をvectorに設定する
(2)vector(動的配列)を昇順でソートして返す
(3)std::coutで結果を出力する
<動作検証&開発環境>
Visual Studio Community 2019
Version16.1.1
<イメージ>
<使い方>
Windowsデスクトップウィザードでプロジェクトを作成する
コンソールアプリケーション(.exe)を指定する
ソースを追加する
(1)ファイルピッカーで画像ファイルを選択します
(2)シートに画像ファイルのハイパーリンクを設定します
(3)シートの画像ファイルのサムネイルを設定します
<実行イメージ>
<動作検証>
Microsoft Office 365 バージョン1905(11629.20214)
<使い方>
適当なところにソースを貼り付けてください
画像をシートに並べて表示する() を実行します
'/********************************************************
'/* 画像をシートに並べてハイパーリンクを設定する
'/* 1.画像ファイル(.jpg)を選択する(複数選択可)
'/* 2.画像ファイルのサムネイルをシートに並べる
'/* 3.画像ファイルへのハイパーリンクをシートに設定する
'/********************************************************
Public Sub 画像をシートに並べて表示する()
On Error GoTo ErrorOccurred
Dim gazoFiles() As String
Dim iret As Integer, i As Integer
Dim stcol As Integer, strow As Integer
Dim filename As String
'//ファイル選択ダイアログで画像ファイルを選択する
With Application.FileDialog(msoFileDialogFilePicker)
'選択可能ファイル(.jpg)設定
.Filters.Add "画像ファイル(Jpeg)", "*.jpg"
'複数ファイル選択可能
.AllowMultiSelect = True
'ファイルピッカー表示
If .Show = False Then
Exit Sub
Else
'SelectedItemsはインデックス1から開始するのでFor文で実装する際は注意
i = 0
For Each tmpstr In .SelectedItems
ReDim Preserve gazoFiles(i)
gazoFiles(i) = tmpstr
i = i + 1
Next
End If
End With
'//シートを初期化していいか確認メッセージを表示する
iret = MsgBox(ActiveSheet.Name & " : シートを初期化してもよろしいですか?", _
vbYesNo + vbQuestion, "画像をシートに並べて表示する")
If iret = vbNo Then Exit Sub
'//シートを初期化する
シートクリア ActiveSheet.Name
'//画像のサムネイルとハイパーリンクを設定
i = 1
stcol = 2
strow = 2
For Each tmpstr In gazoFiles
'ハイパーリンクを設定
'詳細はOfficeデベロッパーセンター参照
filename = Mid(tmpstr, InStrRev(tmpstr, "¥") + 1)
Range(Cells(strow, stcol), Cells(strow, stcol)).Select
ActiveSheet.Hyperlinks.Add _
Anchor:=ActiveSheet.Range(Cells(strow, stcol), Cells(strow, stcol)), _
Address:=tmpstr, _
ScreenTip:=tmpstr, _
TextToDisplay:=filename
'サムネイル画像を設定
Range(Cells(strow + 1, stcol), Cells(strow + 1, stcol)).Select
ActiveSheet.Pictures.Insert(tmpstr).Select
Selection.ShapeRange.Height = 150
'次の開始位置を算出(横方向は最大4画像とする)
If (i Mod 4) = 0 Then
stcol = 2
strow = strow + 12
Else
stcol = stcol + 13
End If
'次の画像はi番目
i = i + 1
Next
Range("A1").Select
Exit Sub
ErrorOccurred:
MsgBox "何かエラーが発生しました", vbCritical
End Sub
'/********************************************************
'/ シートをクリアする
'/ stname:クリア対象シート名
'/********************************************************
Private Sub シートクリア(ByVal stname As String)
Dim sp As Variant
'//シート選択
ThisWorkbook.Sheets(stname).Activate
'//セルを初期化する
Cells.Select
Selection.UnMerge
Selection.Clear
Selection.ColumnWidth = 3
Selection.RowHeight = 17
Selection.Font.Name = "Meiryo UI"
Selection.Font.Size = 12
Selection.Borders.LineStyle = False
'//中央揃えを設定
Selection.HorizontalAlignment = xlLeft
Selection.VerticalAlignment = xlCenter
'//セルの折り返しを解除
Selection.WrapText = False
'//オートシェイプを削除する
For Each sp In ActiveSheet.Shapes
sp.Delete
Next
ActiveWindow.Zoom = 80
Range("A1").Select
End Sub
よろしければポチッと押してください
]]>
(1)エディットボックスに入力された2進数文字列を10進数文字列に変換する
(2)エディットボックスに入力された10進数文字列を2進数文字列に変換する
<動作検証&開発環境>
Visual Studio Community 2017
Version15.9.7
<イメージ>
<使い方>
(1)MFCアプリケーションでプロジェクトを作成
(2)アプリケーションの種類に ダイアログベース を指定
(3)ダイアログにUIを配置する
(4)エディットボックスにメンバ変数を追加する
※UpdateDataでアクセスするため
(5)ラベルにメンバ変数を追加する
※UpdateDataでアクセスするため
(6)ソースを追加する
MFCApplication1Dlg.h
class CMFCApplication1Dlg : public CDialogEx
{
//~~省略~~
public:
afx_msg void OnBnClickedButton1();
CString m_Edit1;
CButton *cb;
CString m_Label1;
};
MFCApplication1Dlg.cpp
//プロトタイプ宣言
CString ConvertBinary2Decimal(CString moji);
CString ConvertDecimal2Binary(CString moji);
CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent)
, m_Edit1(_T(""))
, m_Label1(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_Edit1);
DDX_Text(pDX, IDC_Label1, m_Label1);
}
BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//〜〜省略〜〜
//ラジオボタンの初期値を設定
cb = (CButton*)GetDlgItem(IDC_RADIO1);
cb->SetCheck(TRUE);
return TRUE;
}
/******************************************************
ボタンクリックイベントハンドラ
ラジオボタンの選択により処理を分岐する
2進数を10進数に変換:ConvertBinary2Decimal
10進数を2進数に変換:ConvertDecimal2Binary
******************************************************/
void CMFCApplication1Dlg::OnBnClickedButton1()
{
CString cs,csRet;
//エディットボックスの内容をメンバ変数にセット
UpdateData(TRUE);
if (m_Edit1.GetLength() == 0) return;
//入力文字列チェック&変換
if (cb->GetCheck())
{
//入力値チェック
if (m_Edit1 != m_Edit1.SpanIncluding(L"01"))
{
AfxMessageBox(L"2進数は0か1を入力してください", MB_ICONERROR);
return;
}
else
{
//上限桁数はunsigned intのマックス値まで
if (m_Edit1.GetLength() > 32)
{
AfxMessageBox(L"入力2進数は32桁がマックス値です", MB_ICONERROR);
return;
}
}
//2進数から10進数に変換
m_Label1 = ConvertBinary2Decimal(m_Edit1);
UpdateData(FALSE);
}
else
{
//入力値チェック
if (m_Edit1 != m_Edit1.SpanIncluding(L"0123456789"))
{
AfxMessageBox(L"10進数は0-9の数値を入力してください", MB_ICONERROR);
return;
}
else
{
//上限桁数はunsigned intのマックス値まで
if (m_Edit1.GetLength() > 10)
{
AfxMessageBox(L"入力10進数は10桁がマックス値です", MB_ICONERROR);
return;
}
else if (m_Edit1.GetLength() == 10)
{
if (m_Edit1 > L"4294967295")
{
AfxMessageBox(L"入力10進数はunsigned intの上限がマックス値です", MB_ICONERROR);
return;
}
}
}
//10進数から2進数に変換
m_Label1 = ConvertDecimal2Binary(m_Edit1);
UpdateData(FALSE);
}
}
/******************************************************
2進数文字列を10進数文字列に変換する
符号なし/unsigned intのマックス値まで変換可能
引 数:2進数文字列
戻り値:10進数文字列
******************************************************/
CString ConvertBinary2Decimal(CString moji)
{
CString csRet(L""),cwk;
unsigned int uiRet = 0;
for (int i = 0; i < moji.GetLength(); i++)
{
cwk = moji.Mid(i, 1);
if (cwk == L"1")
{
uiRet += (unsigned int)pow(2, (moji.GetLength() - 1) - i);
}
}
csRet.Format(L"%u",uiRet);
return csRet;
}
/******************************************************
10進数文字列を2進数文字列に変換する
符号なし/unsigned intのマックス値まで変換可能
引 数:10進数文字列
戻り値:2進数文字列
******************************************************/
CString ConvertDecimal2Binary(CString moji)
{
CString csRet(L""), cwk;
wchar_t wt[20];
ZeroMemory(&wt, sizeof(wchar_t) * 20);
wsprintf(wt,L"%s", moji);
unsigned int idecimal = 0,ui;
//_ttoiによる数値変換だとintの最大値に丸められるため独自に計算する
//idecimal = _ttoi(moji)
for (int i = 0; i < moji.GetLength(); i++)
{
cwk = moji.Mid(i, 1);
ui = _ttoi(cwk);
idecimal += ((unsigned int)pow(10, (moji.GetLength() - 1) - i) * ui);
}
unsigned int syo, amari;
for(;;)
{
syo = idecimal / 2;
amari = idecimal % 2;
cwk.Format(L"%u",amari);
csRet = (cwk + csRet);
//商が0になったら終了
if (syo == 0) break;
idecimal = syo;
}
return csRet;
}
よろしければポチッと押してください
(1)FileSystemObjectのGetFileメソッドでファイル情報を取得する
(2)Openステートメントでバイナリファイルの指定位置から指定サイズだけ切り出す
<イメージ>
ファイル情報を出力します
バイナリファイルの指定位置から指定サイズ分取得して別ファイルに切り出します
※サンプルでは50000バイト目から10000バイト分を切り出します
<動作検証&開発環境>
Microsoft Office 2016
<使い方>
(1)参照設定を行います
[Alt]+[F11]でVBE(VBAエディター)を表示します
メニューの[ツール(T)]から[参照設定(R)]を選択します
Microsoft Scripting Runtimeをチェックして[OK]を押下してください
(2)標準モジュールを追加します
(3)ソースを貼り付けます
'********************************************
'ファイル情報を表示する
'GetFileの詳細はDeveloperNetwork参照
'********************************************
Public Sub ファイル情報を表示する()
On Error GoTo lblerror
Dim filename As String
Dim myfso As FileSystemObject, myinfo As Object
Dim sret As String
'//テストファイルパス
filename = ThisWorkbook.Path + "¥testpicture.jpg"
'//FSOオブジェクトを取得する
Set myfso = CreateObject("Scripting.FileSystemObject")
'//ファイル情報を取得する
Set myinfo = myfso.GetFile(filename)
sret = "【File】" + vbCrLf
'//パス
sret = sret + myinfo.Path + vbCrLf
'//ファイル名
sret = sret + myinfo.Name + vbCrLf
'//ファイルサイズ
sret = sret + CStr(myinfo.size) + "バイト" + vbCrLf
'//ファイルタイプ
sret = sret + myinfo.Type + vbCrLf
'//ファイル作成日時・最終アクセス日時・最終更新日時
sret = sret + "作成日時 :" + DateFormat(myinfo.DateCreated) + vbCrLf
sret = sret + "最終アクセス日時:" + DateFormat(myinfo.DateLastAccessed) + vbCrLf
sret = sret + "最終更新日時 :" + DateFormat(myinfo.DateLastModified) + vbCrLf
'//フォルダ作成日時・最終アクセス日時・最終更新日時
sret = sret + "【Folder】" + vbCrLf
sret = sret + "作成日時 :" + DateFormat(myinfo.ParentFolder.DateCreated) + vbCrLf
sret = sret + "最終アクセス日時:" + DateFormat(myinfo.ParentFolder.DateLastAccessed) + vbCrLf
sret = sret + "最終更新日時 :" + DateFormat(myinfo.ParentFolder.DateLastModified) + vbCrLf
MsgBox sret, vbInformation
lblerror:
Set myinfo = Nothing
Set myfso = Nothing
End Sub
'********************************************
'Date型の書式を設定する
'********************************************
Private Function DateFormat(ByVal dt As Date) As String
DateFormat = Format(dt, "yyyy-mm-dd hh:nn:ss")
End Function
'********************************************
'指定位置から指定サイズ切り出して保存する
'********************************************
Public Sub バイナリファイルから指定サイズ切り出す()
On Error GoTo lblerror
Dim readfile As String, writefile As String
Dim rfl As Long, lidx As Long, wfl As Long
'//切り出す開始位置とサイズ
'//アドレス0xC350(50000)から10000バイト切り出す
Dim myichi As Long
myichi = 0
Dim mysize As Long
mysize = 2910731
'//ファイル指定
readfile = ThisWorkbook.Path + "¥testpicture.jpg"
writefile = ThisWorkbook.Path + "¥testbinary.bin"
'//バッファ
Dim rbuf() As Byte
Dim wbuf() As Byte
'//ファイルを開く
rfl = FreeFile
Open readfile For Binary Access Read As rfl
'//書き込みファイルが存在する場合は中身をいったんクリアする
wfl = FreeFile
If Dir(writefile) <> "" Then
Open writefile For Output As wfl
Close (wfl)
End If
Open writefile For Binary Access Write As wfl
'//読み込み
ReDim rbuf(LOF(rfl))
Get rfl, , rbuf
'//書き込み
ReDim wbuf(mysize)
For lidx = 0 To LOF(rfl) - 1
If lidx < myichi Then GoTo nextbyte
If lidx > (myichi + mysize - 1) Then Exit For
Put wfl, , rbuf(lidx)
nextbyte:
Next
Close rfl
Close wfl
Exit Sub
lblerror:
MsgBox "何かエラーが発生しました", vbCritical
End Sub
よろしければポチッと押してください
]]>(1)RegOpenKeyExでレジストリをオープンします
HKEY_LOCAL_MACHINE
SOFTWARE¥Microsoft¥Windows NT¥CurrentVersion
(2)RegQueryValueExを使ってレジストリの値を取得します
ProductName
ReleaseId
CurrentBuildNumber
UBR
(3)Windows10のバージョン情報を表示します
<動作検証&開発環境>
Visual Studio Community 2017
<イメージ>
OS Windows 10 Enterprise
バージョン 1803
OSビルド 17134.345
<使い方>
(1)プロジェクトの選択でデスクトップウィザードを指定します
アプリケーションの種類:コンソールアプリケーション
共通ヘッダの追加:MFCにチェック
(2)コードを記述します
//プロトタイプ宣言
CString GetWindows10Version();
CString GetRegDataText(DWORD dwType, DWORD dwSize, TCHAR *buf, CString csEntry);
const int DMAX_SIZE = 256;
int main()
{
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
//〜〜省略〜〜
}
else
{
//Window10のバージョン情報をレジストリから取得
CString csRet = GetWindows10Version();
//結果を出力
AfxMessageBox(csRet, MB_ICONINFORMATION);
}
}
else
{
//〜〜省略〜〜
}
return nRetCode;
}
/******************************************************
GetWindows10Version
レジストリからRegQueryValueExを使用してバージョン情報を取得する
戻り値
バージョン情報(タイプ/サイズ/値)
******************************************************/
CString GetWindows10Version()
{
HKEY hKey = nullptr; //レジストリキーのハンドル
LONG lRet;
CString csRet=_T("");
TCHAR buf[DMAX_SIZE];
DWORD dwSize,dwType,dwVal=0;
//レジストリオープン
lRet = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("SOFTWARE¥¥Microsoft¥¥Windows NT¥¥CurrentVersion"),
0,
KEY_QUERY_VALUE,
&hKey
);
//レジストリオープンエラー
if (lRet != ERROR_SUCCESS)
{
csRet = _T("RegOpenKeyExエラー");
goto lbl_Error;
}
//RegQueryValueExについてはDeveloperNetwork参照
//// プロダクト(OS)を取得 //////////
dwSize = DMAX_SIZE;
ZeroMemory(&buf, DMAX_SIZE*2);
lRet = RegQueryValueEx(
hKey,
_T("ProductName"),
0,
&dwType,
(LPBYTE)buf,
&dwSize
);
//プロダクト 値取得エラー
if (lRet != ERROR_SUCCESS)
{
csRet = _T("RegQueryValueEx(ProductName)エラー");
goto lbl_Error;
}
csRet = _T("【Windows Version情報】¥r¥n");
csRet += GetRegDataText(dwType, dwSize, buf, _T("ProductName"));
//// リリースIDを取得 //////////
dwSize = DMAX_SIZE;
ZeroMemory(&buf, DMAX_SIZE * 2);
lRet = RegQueryValueEx(
hKey,
_T("ReleaseId"),
0,
&dwType,
(LPBYTE)buf,
&dwSize
);
//リリースID 値取得エラー
if (lRet != ERROR_SUCCESS)
{
csRet = _T("RegQueryValueEx(ReleaseId)エラー");
goto lbl_Error;
}
csRet += GetRegDataText(dwType, dwSize, buf,_T("ReleaseId"));
//// ビルドバージョンを取得 //////////
dwSize = DMAX_SIZE;
ZeroMemory(&buf, DMAX_SIZE * 2);
lRet = RegQueryValueEx(
hKey,
_T("CurrentBuildNumber"),
0,
&dwType,
(LPBYTE)buf,
&dwSize
);
//ビルドバージョン 値取得エラー
if (lRet != ERROR_SUCCESS)
{
csRet = _T("RegQueryValueEx(CurrentBuildNumber)エラー");
goto lbl_Error;
}
csRet += GetRegDataText(dwType, dwSize, buf, _T("CurrentBuildNumber"));
//// ビルドバージョン(UBR)を取得 //////////
dwSize = DMAX_SIZE;
ZeroMemory(&buf, DMAX_SIZE * 2);
lRet = RegQueryValueEx(
hKey,
_T("UBR"),
0,
&dwType,
(LPBYTE)buf,
&dwSize
);
//ビルドバージョン(UBR) 値取得エラー
if (lRet != ERROR_SUCCESS)
{
csRet = _T("RegQueryValueEx(UBR)エラー");
goto lbl_Error;
}
csRet += GetRegDataText(dwType, dwSize, buf, _T("UBR"));
lbl_Error:
if (hKey != NULL)
{
//レジストリクローズ
RegCloseKey(hKey);
}
return csRet;
}
/******************************************************
GetRegDataText
取得したタイプ(データ型)/サイズ/値より表示用文字列を生成
引数
dwType : タイプ(データ型)
dwSize : データサイズ
buf : レジストリの値
csEntry : レジストリのエントリ名
戻り値
表示用文字列
******************************************************/
CString GetRegDataText(DWORD dwType,DWORD dwSize,TCHAR *buf,CString csEntry)
{
CString csRet = _T("¥r¥n=== ") + csEntry + _T(" ==========¥r¥n");
CString cwk;
int iwk;
//読みだしたタイプに応じてサイズと値を設定
//ここでは必要なタイプのみ設定するがタイプの詳細はDeveloperNetwork参照
switch (dwType)
{
case REG_DWORD:
iwk = (int)buf[0];
cwk.Format(_T(" VALUE: %d¥r¥n SIZE: %d TYPE: REG_DWORD¥r¥n"), iwk, dwSize);
break;
case REG_SZ:
cwk.Format(_T(" VALUE: %s¥r¥n SIZE: %d TYPE: REG_SZ¥r¥n"), buf, dwSize);
break;
}
csRet += cwk;
return csRet;
}
よろしければポチッと押してください
FSO(FileSystemObject)を使ってファイルの読み・書き・追記を行うサンプルです
(1)ファイルにテキストを書き込む
(2)ファイルにテキストを追記する
(3)ファイルからテキストを読み込む
(4)フォルダを作成する
(5)ファイルを別フォルダにリネームしてコピーする
(6)ファイルをワイルドカードを使用して別フォルダにコピーする
(7)ファイルを削除する
<実行イメージ>
上記(1)〜(7)実行後のイメージです
(1)(2) ファイル書き込み・追記を行います
(3) 追記を行ったファイルを読み込み結果をシートに出力します
(4)(5) フォルダを作成し作成したファイルを100回コピーします
(6) 100回コピーされたファイルを別フォルダにワイルドカードを使用してコピーします
(7) コピーしたファイルからファイル末尾に不可した数値が10の倍数のファイルを削除します
<動作検証&開発環境>
Microsoft Office 2016
<使い方>
(1)参照設定を行います
[Alt]+[F11]でVBE(VBAエディター)を表示します
メニューの[ツール(T)]から[参照設定(R)]を選択します
Microsoft Scripting Runtimeをチェックして[OK]を押下してください
これによりForReading / TristateFalseなどの定数が使用できるようになります
(2)標準モジュールを追加してソースを貼り付けます
(3)「FSOでファイルを操作する」 プロシージャを実行します
(1)CreateEllipticRgnで楕円形のリージョン(Crgn)を作成します
(2)CreateRectRgnで四角形のリージョン(CRgn)を作成します
(3)CombineRgnでリージョンを結合します
(4)SetWindowRgnで非矩形ウィンドウを作成します
<動作検証&開発環境>
Visual Studio Community 2017
<イメージ>
元のダイアログ
[楕円1個]ボタン押下により楕円形のウィンドウに切り替え
[楕円2個]ボタン押下により楕円形2個のウィンドウに切り替え
[楕円くり抜き]ボタン押下により左右の矩形と楕円をXORしたウィンドウに切り替え
CombineRgnされた矩形ダイアログと楕円ダイアログのXOR部分が透明になります
<使い方>
(1)MFCアプリケーションでプロジェクトを作成
(2)アプリケーションの種類でダイアログベースを選択
(3)生成されたクラスで基底クラスにCDialogを選択
(4)MFCApplication1.rcを下記の通り修正
※MFCApplication1は各環境のプロジェクト名
(5)クラスウィザードでWM_NCHITTESTメッセージを追加
※非矩形ウィンドウはタイトルバーがなくなるためタイトルバー以外でドラッグ移動できるようにする
(6)ボタンを追加します(ダイアログの中央に集めてください)
(7)ソースを追加します
よろしければポチッと押してください
(1)ファイル選択ダイアログでファイルを指定します
(2)指定ファイルのCFile::GetStatusでファイルステータスを取得します
CTime | m_ctime | ファイルの作成日時 |
CTime | m_mtime | ファイルの最終更新日時 |
CTime | m_atime | ファイルが読み取りで最後にアクセスされた日時 |
ULONGLONG | m_size | ファイルの論理サイズ |
BYTE | m_attribute | ファイル属性 |
char | m_szFullName | ファイルパス |
(3)ファイル属性(m_attribute)を取得します
(4)ファイルステータスの取得結果をメッセージボックスで表示します
<動作検証&開発環境>
Visual Studio Community 2017
<イメージ>
<使い方>
(1)"Windowsデスクトップウィザード" を選択します
(2)コンソールアプリケーション(.exe)を選択します
(3)MFCにチェックを入れます
(4)コードを記述します
よろしければポチッと押してください
]]>
(1)VBAで3D迷路(プチゲーム)を作ってみる 後編 です
前回は3Dマップ表示まで行いました
(前回 オートシェイプで3D迷路を作ってみる(前編) )
今回はコマンドボタン(前、左、右)によって移動できます
感動のエンディング www もご覧ください
(2)マップ表示はオートシェイプを使用します
(3)全体マップと3D表示マップを実装しました
全体マップ:20×20の全体マップです(スタートとゴールに●を表示します)
3Dマップ:縦8階層×横9ブロックの3D表示の元データです
(4)3Dマップは常にユーザの正面目線で描画しています
全体マップで北向きのとき:ユーザの現在位置の上側を描画
全体マップで東向きのとき:ユーザの現在位置の右側を描画
全体マップで南向きのとき:ユーザの現在位置の下側を描画
全体マップで西向きのとき:ユーザの現在位置の左側を描画
(5)コマンドボタンは「前進む」「左向く」「右向く」を実装しました
(6)3D表示エリアは64セル×64セルです
正面(後方)の壁の四角形、横壁の台形表示とセル数との関係は以下の通りです
(7)前回の3Dマップ描画で壁が足りなかった部分を修正しました
四角形と台形の表示処理
1)壁(情報コード=9、99)のときの3D描画
・描画対象外(目に見えない範囲 情報コード=7、8)ならスキップ
・手前の壁(四角形)を描画する
2)通路(情報コード=1、2、0)のときの3D描画
・中央より左(0から3)のとき、左が壁なら左側に台形を描画
・中央より右(5から7)のとき、右が壁なら右側に台形を描画
・中央(4)のとき左が壁なら左側、右が壁なら右側、両方なら両方に台形を描画
3)通路のとき前のブロックが壁なら前面に四角形を描画
<実行イメージ>
YouTubeに動画アップしましたのでご覧ください
<動作検証>
Microsoft Office 2016
<使い方>
適当なところにソースを貼り付けてください
シート初期化() を実行すると3D迷路を描画します
※アクティブセルの情報を全てクリアしますのでご注意ください
ソースは3Dマップ描画部のみ掲載します
下記URLで完全版を公開しております
http://sagami-ss.sub.jp/pg-sample/src/Excel_3DMaze_SourceCode.txt
(1)VBAで3D迷路(プチゲーム)を作ってみます
今回は3Dを表示するところまでです
サンプルマップを5種類切り替えて表示します
次回、マップ上を移動できるようにするつもりです(お盆には完成させたい)
(2)3D迷路に必要な台形描画はオートシェイプを使用します
(3)3D迷路の仕様
(3)-1.マップの大きさは64×64セルとします
(3)-2.正面の壁、横の壁はオートシェイプを使用します
(3)-3.奥行きは8階層(インデックス0から7とし0が最奥、7が手前です)
・最奥は壁9ブロック、手前は壁1ブロック
・座標が通路でとなりが壁の時に横壁を表示します(台形を描画)
・横壁は中央より左の時は右辺が短い台形、中央より右の時は左辺が短い台形
(3)-4.描画は奥から順番に行います(結果として見えない壁も描画処理します)
(3)-5.階層別の壁と台形の表示位置は下図の通りです
・上の図の赤色分部が台形(横の壁)を描画するときの台形の幅
・下図の灰色分部がマップ表示されない部分(見えない部分)
<実行イメージ>
シート初期化()実行直後
下の画像を見るとまだまだ横の壁の表示処理が足りない、、、汗
次回、修正します
[次のサンプルマップ]押下によりサンプルが切り替わります
<動作検証>
Microsoft Office 2016
<使い方>
適当なところにソースを貼り付けてください
シート初期化() を実行すると3D迷路を描画します
※アクティブセルの情報を全てクリアしますのでご注意ください
]]>
(1)MFCのSDIアプリケーションにマウスイベントを追加します
WM_MOUSELEAVE : ウィンドウのクライアント領域を離れた
WM_MOUSEMOVE : マウスカーソルが動いた
WM_RBUTTONDOWN : マウスの右ボタンが押下された
WM_RBUTTONUP : マウスの右ボタンが解放された
(2)マウスの右ボタンでクライアント領域をドラッグすると四角形を描画します
CDC->Rectangle
(3)メニューで描画する四角形の塗りつぶし色、線の種類を変更できます
塗りつぶし色
・赤系の色
・緑系の色
・青系の色
線のスタイル
・実線(PS_SOLID)
・破線(PS_DASH)
・点線(PS_DOT)
<実行イメージ>
メニューを指定すると描画する四角形の色と線のスタイルが変更できます
マウスの右ボタン押下するとスタート位置セット、
マウスの右ボタンUPすると終了位置をセットして四角形を描画します
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.MFCアプリケーションでプロジェクトを作成
2.アプリケーションの種類でシングルドキュメントを選択
※その他の設定は下図参照
3.ユーザーインターフェイス機能でクラシックメニューを使用するを選択
※その他の設定は下図参照
4.高度な機能で不要なチェックを外す
5.プロジェクト構成を確認してソースを追加する
6.クラスウィザードでCChileViewクラスにマウスイベントハンドラを追加
WM_MOUSELEAVE : クライアント領域の外にカーソルが移動したとき座標を初期化
WM_MOUSEMOVE : 移動中のマウスカーソルを変更する
WM_RBUTTONDOWN : マウスの右ボタンでスタート座標取得
WM_RBUTTONUP : マウスの右ボタンUPで終了座標取得して描画
7.リソースの[Menu]->[IDR_MAINFRAME]を修正してメニュー項目を追加
以下項目を追加します
赤系の色 : ID_32771
緑系の色 : ID_32772
青系の色 : ID_32773
――境界線をセット――
実線 : ID_32774
破線 : ID_32775
点線 : ID_32776
※塗りつぶし色と線のスタイルはCheckMenuRadioItemでそれぞれグループ化します
メニューのIDはここではID_32771~ID32776ですがソース内もそれぞれの環境に応じて変更してください
8.クラスウィザードでCMainFrameにOnCommandを追加します
メニューが操作されたとき塗りつぶし色、線のスタイルを変更する
MFCApplication1.h
class CMFCApplication1App : public CWinApp
{
//〜〜省略〜〜
//グローバル変数
public:
//メニューでの選択値
COLORREF selClr;
COLORREF selLinfClr;
int iSelStyle;
};
extern CMFCApplication1App theApp;
MainFrm.h
class CMainFrame : public CFrameWnd
{
//〜〜省略〜〜
private:
//塗りつぶしの色
COLORREF clr[3] = {
RGB(216,130,187),
RGB(146,208,80),
RGB(155,194,230)
};
//線の色
COLORREF lineclr[3] = {
RGB(199,73,157),
RGB(97,148,40),
RGB(47,117,181)
};
//線のスタイル
int iStyle[3] = {
PS_SOLID,
PS_DASH,
PS_DOT
};
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
};
MainFrm.cpp
#include "stdafx.h"
#include "MFCApplication1.h"
#include "MainFrm.h"
//CMainFrameオブジェクト
extern CMFCApplication1App theApp;
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//〜〜省略〜〜
CMenu *pMenu = this->GetMenu();
//ON_COMMAND ハンドラーが自動的に無効になるのを停止
CFrameWnd::m_bAutoMenuEnable = FALSE;
//全てのメニューを有効化
pMenu->EnableMenuItem(ID_32771, MF_BYCOMMAND | MF_ENABLED);
pMenu->EnableMenuItem(ID_32772, MF_BYCOMMAND | MF_ENABLED);
pMenu->EnableMenuItem(ID_32773, MF_BYCOMMAND | MF_ENABLED);
pMenu->EnableMenuItem(ID_32774, MF_BYCOMMAND | MF_ENABLED);
pMenu->EnableMenuItem(ID_32775, MF_BYCOMMAND | MF_ENABLED);
pMenu->EnableMenuItem(ID_32776, MF_BYCOMMAND | MF_ENABLED);
//色のメニューをグループ化して赤系にチェックOn
//CheckMenuRadioItemについてはDeveloperNetwork参照
pMenu->CheckMenuRadioItem(ID_32771, ID_32773, ID_32771, MF_BYCOMMAND);
//線のメニューをグループ化して実線にチェックOn
pMenu->CheckMenuRadioItem(ID_32774, ID_32776, ID_32774, MF_BYCOMMAND);
//初期値をセット
theApp.selClr = clr[0];
theApp.selLinfClr = lineclr[0];
theApp.iSelStyle = iStyle[0];
return 0;
}
/***********************************************************
OnCommand
メニューが変更されたら塗りつぶし色、線の種類を変更
※環境に応じてメニューのIDは変更してください
***********************************************************/
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
int iSelClr = 0;
int iSelStyle = 0;
CMenu *pMenu = this->GetMenu();
//現在(変更前)のメニューの状態を取得
if (pMenu->GetMenuState(ID_32771, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelClr = 0;
if (pMenu->GetMenuState(ID_32772, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelClr = 1;
if (pMenu->GetMenuState(ID_32773, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelClr = 2;
if (pMenu->GetMenuState(ID_32774, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelStyle = 0;
if (pMenu->GetMenuState(ID_32775, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelStyle = 1;
if (pMenu->GetMenuState(ID_32776, MF_BYCOMMAND | MF_CHECKED) & MF_CHECKED) iSelStyle = 2;
//変更されたメニュー項目(iItem)で更新
UINT iItem = LOWORD(wParam);
switch (iItem)
{
case ID_32771:
iSelClr = 0;
break;
case ID_32772:
iSelClr = 1;
break;
case ID_32773:
iSelClr = 2;
break;
case ID_32774:
iSelStyle = 0;
break;
case ID_32775:
iSelStyle = 1;
break;
case ID_32776:
iSelStyle = 2;
break;
default:
;
}
//塗りつぶしグループの値を変更
if (iItem == ID_32771 || iItem == ID_32772 || iItem == ID_32773)
{
pMenu->CheckMenuRadioItem(ID_32771, ID_32773, iItem, MF_BYCOMMAND);
theApp.selClr = clr[iSelClr];
theApp.selLinfClr = lineclr[iSelClr];
}
//線の種類グループの値を変更
if (iItem == ID_32774 || iItem == ID_32775 || iItem == ID_32776)
{
pMenu->CheckMenuRadioItem(ID_32774, ID_32776, iItem, MF_BYCOMMAND);
theApp.iSelStyle = iStyle[iSelStyle];
}
TRACE(L"iSelClr=%d iSelStyle=%d¥r¥n",iSelClr, iSelStyle);
return CFrameWnd::OnCommand(wParam, lParam);
}
ChildView.h
class CChildView : public CWnd
{
//〜〜省略〜〜
public:
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
private:
void DrawRectangle();
//描画中フラグ(描画中のときTRUE)
BOOL bDrawing;
//座標情報
CPoint stPoint, edPoint;
};
ChildView.cpp
#include "stdafx.h"
#include "MFCApplication1.h"
#include "ChildView.h"
//CMainFrameオブジェクト
extern CMFCApplication1App theApp;
BEGIN_MESSAGE_MAP(CChildView, CWnd)
//〜〜省略〜〜
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()
/***********************************************************
OnRButtonDown
子ウィンドウでマウスの右ボタンが押下されたイベント
***********************************************************/
void CChildView::OnRButtonDown(UINT nFlags, CPoint point)
{
bDrawing = TRUE;
SetCursor(LoadCursor(NULL,IDC_SIZEALL));
//開始位置を終了位置を初期化
stPoint.SetPoint(0, 0);
edPoint.SetPoint(0, 0);
//開始位置をセット
stPoint = point;
CWnd::OnRButtonDown(nFlags, point);
}
/***********************************************************
OnRButtonUp
子ウィンドウでマウスの右ボタンが離されたイベント
***********************************************************/
void CChildView::OnRButtonUp(UINT nFlags, CPoint point)
{
if (bDrawing)
{
SetCursor(LoadCursor(NULL,IDC_ARROW));
//終了位置をセット
edPoint = point;
//四角形を描画する
DrawRectangle();
}
bDrawing = FALSE;
CWnd::OnRButtonUp(nFlags, point);
}
/***********************************************************
OnMouseMove
マウスが移動中に発生するイベント
***********************************************************/
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
if (bDrawing)
{
SetCursor(LoadCursor(NULL,IDC_SIZEALL));
}
//WM_MOUSELEAVEイベントを受け取れるようにしておく
//TrackMouseEventについてはDeveloperNetwork参照
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = WM_NCMOUSELEAVE;
tme.hwndTrack = this->GetSafeHwnd();
tme.dwHoverTime = 0; //関係ないので0をセットしておく
TrackMouseEvent(&tme);
CWnd::OnMouseMove(nFlags, point);
}
/***********************************************************
OnMouseLeave
子ウィンドウのクライアント領域をマウスが離れたイベント
描画フラグとアイコンをリセットする
***********************************************************/
void CChildView::OnMouseLeave()
{
bDrawing = FALSE;
SetCursor(LoadCursor(NULL, IDC_ARROW));
TRACE(L"OnMouseLeave¥r¥n");
CWnd::OnMouseLeave();
}
/***********************************************************
DrawRectangle
開始Pointと終了Pointに対して四角形を描画する
塗りつぶし色、線の色、線のスタイルはメニューの選択値を取得
***********************************************************/
void CChildView::DrawRectangle()
{
CDC *pDC = this->GetDC();
//四角形を塗りつぶすブラシ
CBrush brs(theApp.selClr);
CBrush *pOldBrush = pDC->SelectObject(&brs);
//四角形を描画するペン
//1より大きな幅を指定するとPS_SOLIDスタイルになるため幅は0とする
CPen pen;
pen.CreatePen(theApp.iSelStyle, 0, theApp.selLinfClr);
CPen *pOldPen = pDC->SelectObject(&pen);
//四角形を描画する領域
CRect rect(stPoint,edPoint);
//参考情報として出力ウィンドウに座標表示
CString cs;
cs.Format(L"st.x=%d st.y=%d ed.x=%d ed.y=%d¥r¥n",
stPoint.x, stPoint.y, edPoint.x, edPoint.y);
TRACE(cs);
//四角形を描画
pDC->Rectangle(rect);
//オブジェクトを戻す
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
よろしければポチッと押してください
]]>
(1)MFCのSDIアプリケーションにリストコントロール(CListCtrl)を追加する
(2)リストコントロールをCreate(サイズ・WindowStyle指定)する
(3)リストコントロールのフォントを変更してみる(MS UI Gothic使用)
(4)ヘッダ設定(InsertColumn)、データ設定(InsertItem)を行う
(5)イベントを追加する(WindowProc)
・LVN_ITEMCHANGED : リストコントロールに変更があった
・LVN_COLUMNCLICK : リストコントロールのヘッダが左クリックされた
<実行イメージ>
フォントをMS UI Gothicに変更しヘッダ・データをセット
※データは東京都の市区町村別人口
リスト選択により選択行番号と選択行の情報を表示
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.MFCアプリケーションでプロジェクトを作成
2.アプリケーションの種類でシングルドキュメントを選択
3.ユーザーインターフェイス機能でくクラシックメニューを使用するを選択
※その他の設定は下図参照
4.高度な機能で不要なチェックを外す
5.プロジェクト構成を確認しソースを追加する
6.クラスウィザードにてCChileViewクラスにOnCreateハンドラーを追加
※OnCreateでリストコントロールを生成しデータを設定する
7.クラスウィザードにてCChileViewクラスにWindowProcハンドラーを追加
※WindowProcでリストコントロールのイベント処理を行う
MainFrm.cpp
//メインフレームのサイズ設定を行う
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
| WS_SYSMENU;
//cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
//ウィンドウサイズとクライアント領域を一致させる
cs.dwExStyle = WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
//作業領域のサイズを取得
//画面全体からシステムのタスクバーやアプリケーションのツールバーが占有する領域を除いた部分
CRect rcSpara;
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcSpara, NULL);
//ウィンドウサイズの設定
CRect rect(0, 0, 600, 400);
::AdjustWindowRectEx(&rect, cs.style, TRUE, cs.dwExStyle);
//ウィンドウサイズを取得
cs.cx = rect.Width();
cs.cy = rect.Height();
//画面中央に表示
cs.x = rcSpara.left + (rcSpara.Width() - cs.cx) / 2;
cs.y = rcSpara.top + (rcSpara.Height() - cs.cy) / 2;
return TRUE;
}
ChildView.h
//フォント変更するためCFontオブジェクトを追加
class CChildView : public CWnd
{
//省略~~
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
private:
const int D_IDLISTVIEW = 1000;
void InsertListCtrlItems(CListCtrl *pList);
public:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
CFont *m_pFont;
};
ChildView.cpp
CChildView::CChildView()
{
//子ウィンドにフォントをセット
m_pFont = new CFont;
LOGFONT logFont;
logFont.lfHeight = 12;
logFont.lfWidth = 10;
logFont.lfEscapement = 0;
logFont.lfOrientation = 0;
logFont.lfWeight = FW_DONTCARE;
logFont.lfItalic = FALSE;
logFont.lfUnderline = FALSE;
logFont.lfStrikeOut = FALSE;
logFont.lfCharSet = DEFAULT_CHARSET;
logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logFont.lfQuality = DEFAULT_QUALITY;
logFont.lfPitchAndFamily = FF_DONTCARE;
lstrcpy(logFont.lfFaceName, L"MS UI Gothic");
m_pFont->CreateFontIndirect(&logFont);
}
CChildView::~CChildView()
{
//フォントオブジェクトを破棄
delete m_pFont;
}
/***********************************************************
OnCreate
SDIで子ウィンドウの作成時にリストコントロール(CListCtrl)を生成
***********************************************************/
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//ウィンドウサイズを取得
CFrameWnd *pFrm = GetParentFrame();
CRect rect;
pFrm->GetClientRect(&rect);
//リストコントロール(レポート形式)を配置
//ウィンドウサイズに対して余白10で配置する
CListCtrl *pListctrl = new CListCtrl();
//List-View Window Stylesはデベロッパーセンターを参照
pListctrl->Create(
WS_VISIBLE | WS_BORDER | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_REPORT | LVS_SINGLESEL,
CRect(10, 10, rect.Width()-20, rect.Height()-20), this, D_IDLISTVIEW);
//拡張スタイルを設定
pListctrl->SetExtendedStyle(pListctrl->GetExtendedStyle() | LVS_EX_FULLROWSELECT);
//リストカラムセッティング
LV_COLUMN lvclm;
ZeroMemory(&lvclm, sizeof(LV_COLUMN));
lvclm.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
//インデックス0の列はは常にLVCFMT_LEFTとなる
//詳細はデベロッパーセンターのRemarks参照
//lvclm.fmt = LVCFMT_CENTER;
lvclm.iSubItem = 0;
lvclm.pszText = L"地域コード";
lvclm.cx = 130;
pListctrl->InsertColumn(0, &lvclm);
lvclm.fmt = LVCFMT_LEFT;
lvclm.iSubItem = 1;
lvclm.pszText = L"市区町村名";
lvclm.cx = 250;
pListctrl->InsertColumn(1, &lvclm);
lvclm.fmt = LVCFMT_RIGHT;
lvclm.iSubItem = 2;
lvclm.pszText = L"人口(人)";
lvclm.cx = 150;
pListctrl->InsertColumn(2, &lvclm);
//アイテムセット
InsertListCtrlItems(pListctrl);
//フォントをセット
GetDlgItem(D_IDLISTVIEW)->SetFont(m_pFont);
return 0;
}
/***********************************************************
InsertListCtrlItems
リストコントロールにデータ(東京都市区町村の人口)をセット
***********************************************************/
void CChildView::InsertListCtrlItems(CListCtrl *pList)
{
TCHAR twk[64];
int idx=0;
LVITEM lvitm;
struct
{
int id;
TCHAR name[128];
int population;
}item[]={
{ 13101,_T("東京都 千代田区"),61218 },{ 13102,_T("東京都 中央区"),156256 },
{ 13103,_T("東京都 港区"),253018 },{ 13104,_T("東京都 新宿区"),343533 },
{ 13105,_T("東京都 文京区"),227141 },{ 13106,_T("東京都 台東区"),202947 },
{ 13107,_T("東京都 墨田区"),264229 },{ 13108,_T("東京都 江東区"),510574 },
{ 13109,_T("東京都 品川区"),397710 },{ 13110,_T("東京都 目黒区"),283005 },
{ 13111,_T("東京都 大田区"),728423 },{ 13112,_T("東京都 世田谷区"),921720 },
{ 13113,_T("東京都 渋谷区"),229670 },{ 13114,_T("東京都 中野区"),335745 },
{ 13115,_T("東京都 杉並区"),575841 },{ 13116,_T("東京都 豊島区"),298050 },
{ 13117,_T("東京都 北区"),348547 },{ 13118,_T("東京都 荒川区"),216273 },
{ 13119,_T("東京都 板橋区"),574058 },{ 13120,_T("東京都 練馬区"),731696 },
{ 13121,_T("東京都 足立区"),677514 },{ 13122,_T("東京都 葛飾区"),450846 },
{ 13123,_T("東京都 江戸川区"),691084 },{ 13201,_T("東京都 八王子市"),577910 },
{ 13202,_T("東京都 立川市"),179390 },{ 13203,_T("東京都 武蔵野市"),146381 },
{ 13204,_T("東京都 三鷹市"),190432 },{ 13205,_T("東京都 青梅市"),135789 },
{ 13206,_T("東京都 府中市"),261829 },{ 13207,_T("東京都 昭島市"),111902 },
{ 13208,_T("東京都 調布市"),235243 },{ 13209,_T("東京都 町田市"),434091 },
{ 13210,_T("東京都 小金井市"),123813 },{ 13211,_T("東京都 小平市"),192874 },
{ 13212,_T("東京都 日野市"),188327 },{ 13213,_T("東京都 東村山市"),150180 },
{ 13214,_T("東京都 国分寺市"),124501 },{ 13215,_T("東京都 国立市"),74610 },
{ 13218,_T("東京都 福生市"),58210 },{ 13219,_T("東京都 狛江市"),82357 },
{ 13220,_T("東京都 東大和市"),84664 },{ 13221,_T("東京都 清瀬市"),75377 },
{ 13222,_T("東京都 東久留米市"),116360 },{ 13223,_T("東京都 武蔵村山市"),71651 },
{ 13224,_T("東京都 多摩市"),147691 },{ 13225,_T("東京都 稲城市"),90225 },
{ 13227,_T("東京都 羽村市"),55225 },{ 13228,_T("東京都 あきる野市"),80373 },
{ 13229,_T("東京都 西東京市"),202201 },{ 13303,_T("東京都 西多摩郡瑞穂町"),33102 },
{ 13305,_T("東京都 西多摩郡日の出町"),17404 },{ 13307,_T("東京都 西多摩郡檜原村"),2096 },
{ 13308,_T("東京都 西多摩郡奥多摩町"),5058 },{ 13361,_T("東京都 大島町"),7580 },
{ 13362,_T("東京都 利島村"),343 },{ 13363,_T("東京都 新島村"),2630 },
{ 13364,_T("東京都 神津島村"),1845 },{ 13381,_T("東京都 三宅島三宅村"),2383 },
{ 13382,_T("東京都 御蔵島村"),343 },{ 13401,_T("東京都 八丈島八丈町"),7330 },
{ 13402,_T("東京都 青ヶ島村"),174 },{ 13421,_T("東京都 小笠原村"),3067 },
0
};
for (INT i = 0;; i++)
{
if (item[i].id == 0) break;
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = pList->GetItemCount();
lvitm.iSubItem = 0;
ZeroMemory(&twk, sizeof(twk));
wsprintf(twk, _T("%d"), item[i].id);
lvitm.pszText = twk;
idx = ListView_InsertItem(pList->GetSafeHwnd(), &lvitm);
//idx = pList->InsertItem(&lvitm);
if (idx == (-1))
{
AfxMessageBox(L"InsertItem Error!!",MB_ICONSTOP);
return;
}
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = idx;
lvitm.iSubItem = 1;
lvitm.pszText = item[i].name;
ListView_SetItem(pList->GetSafeHwnd(), &lvitm);
//pList->SetItem(&lvitm);
ZeroMemory(&lvitm, sizeof(LVITEM));
lvitm.mask = LVIF_TEXT;
lvitm.iItem = idx;
lvitm.iSubItem = 2;
ZeroMemory(&twk, sizeof(twk));
wsprintf(twk, _T("%d"), item[i].population);
lvitm.pszText = twk;
ListView_SetItem(pList->GetSafeHwnd(), &lvitm);
//pList->SetItem(&lvitm);
}
}
/***********************************************************
WindowProc
リストコントロールのイベント処理
LVN_ITEMCHANGED : リストコントロールに変更があった
LVN_COLUMNCLICK : リストコントロールのヘッダが左クリックされた
***********************************************************/
LRESULT CChildView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LV_DISPINFO *lvdisp;
NM_LISTVIEW *pNMLV;
CString cs;
int idx;
switch (message)
{
case WM_NOTIFY:
//リストコントロールからのメッセージのみ処理する
if ((int)wParam == D_IDLISTVIEW) {
lvdisp = (LV_DISPINFO *)lParam;
pNMLV = (NM_LISTVIEW *)lParam;
//リストビューを取得
CListCtrl *pListCtrl = (CListCtrl *)GetDlgItem(D_IDLISTVIEW);
//選択されている行のインデックスを取得
idx = pNMLV->iItem;
switch (lvdisp->hdr.code) {
case LVN_ITEMCHANGED:
//選択行の情報を表示する
if ((pNMLV->uChanged & LVIF_STATE) && (pNMLV->uNewState & LVIS_SELECTED)) {
cs.Format(L"%d行目¥r¥n地域コード [%s]¥r¥n市区町村名 [%s]¥r¥n人口 [%s]",
idx+1,pListCtrl->GetItemText(idx, 0),
pListCtrl->GetItemText(idx, 1),
pListCtrl->GetItemText(idx, 2));
AfxMessageBox(cs,MB_ICONINFORMATION);
}
break;
case LVN_COLUMNCLICK:
//iSubItemを参照してヘッダのクリックされた列を表示する
cs.Format(L"ヘッダ行の%d列目が左クリックされました", pNMLV->iSubItem+1);
AfxMessageBox(cs,MB_ICONINFORMATION);
break;
}
}
break;
default:
;
}
return CWnd::WindowProc(message, wParam, lParam);
}
よろしければポチッと押してください
]]>
・フォームにControlをオーナードローします
TextBox×20
OptionButton×60(3個1組でグループ化)
ConboBox×20
Label×20
・フォームのプロパティをスクロールできるよう設定します
ScrollBars(スクロールバーの表示)
ScrollHeight(フォーム全体の高さ)
・クラスモジュール、標準モジュールを追加します
・クラス(WithEvents)でイベントを受け取ります
Class1:OptionButtonクリックイベントのコールバック
Class2:ComboBox選択変更イベントのコールバック
<動作環境>
Microsoft Office 2016
<実行イメージ>
フォームInitializeでコントロールを配置
(テキスト、ラジオ、コンボ、ラベルを20組配置)
<使い方>
フォームを追加します(ID:UserForm1)
ラジオボタンイベント通知クラスを追加します(Class1)
コンボボックスイベント通知クラスを追加します(Class2)
フォーム表示用の標準モジュールを追加します(Module1)
ユーザフォーム表示()を実行するとフォームを表示します
Module1
'/*********************************************
'/ ユーザフォームを表示する
'/*********************************************
Public Sub ユーザフォーム表示()
UserForm1.Show
End Sub
UserForm1
'//イベントを受け取るコントロール
]]>
(1)社員ID(int)、社員名(CString)、通勤費支給(BOOL)を持つクラスを定義
(2)クラスのメンバ変数を operator= でコピーできるようにする
オブジェクトA = オブジェクトB でメンバ変数をコピー
(3)クラスインスタンスを動的配列(std::vector)に operator+ で追加する
(4)追加と同時にソート処理を実施する
オブジェクトA + オブジェクトB でオブジェクトAの動的配列にオブジェクトBを追加
オブジェクトAの動的配列を社員IDの昇順でソート(std::sort)
<実行イメージ>
"出力"ウィンドウに結果を表示します
※表示されていない場合は[表示]メニュー→[出力]
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.プロジェクトの種類でWindowsデスクトップウィザードを選択
2.アプリケーションの種類で「コンソールアプリケーション」を選択
3.共通ヘッダの「MFC」にチェック
4.クラスを追加
クラス名:CShainClass
ファイル名:ShainClass.h
(ShainClass.cppは本サンプルでは使用しません)
5.ソースを追加
ShainClass.h
(1)入力は半角英数のみ、文字数の上限チェックをクラスで実装する
(2)OnEnChangeで半角英数チェックを行う
(3)OnKeyDownで入力文字数の上限チェックを行う
(4)入力制限クラスを複数のエディットボックスに適用する
<実行イメージ>
半角英数チェックと文字数の上限チェックを行う
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.ダイアログベースでMFCApplication1プロジェクトを作成します
2.クラスウィザードでMFCクラスを追加します
基底クラスに「CEdit」を選択
クラス名を「CEditTest」とします
3.クラスウィザードでCEditTestクラスに下記イベントを追加します
OnEnChange : このイベントで半角英数チェックを行います
OnKeyDown : このイベントで上限文字数チェックを行います
4.IDD_MFCAPPLICATION1_DIALOGにエディットボックスを2つ追加します
5.追加したエディットボックスにそれぞれメンバ変数を追加します
・コントロール変数にチェック
・カテゴリ:Control
・変数の種類:CEditTest(CEditTestクラスの変数とする)
・変数名はそれぞれm_Edit1 、 m_Edit2 とします
6.ソースを追加してください
CEditTest.h
CEditTest.cpp
MFCApplication1Dlg.h
MFCApplication1Dlg.cpp
よろしければポチッと押してください
]]>
(1)メールスロットクライアントとサーバを作成します
(2)メールスロットを使って2つのexe間でプロセス間通信を行います
(3)クライアントは[送信]ボタン押下によりメッセージを送付します
(4)サーバは受信メッセージをリストボックスに表示します
(5)クライアント起動時にサーバも起動します
(サーバからクライアントの起動ななし)
<実行イメージ>
上の実行ファイルはメールスロットクライアント(MFCApplication1)
下の実行ファイルはメールスロットサーバ(MFCApplication2)
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.MFCApplication1プロジェクトを作成します
2.MFCApplication1ソリューションにMFCApplication2プロジェクトを追加します
(どちらもダイアログベースです)
サンプルのソリューション構成
MFCApplication1(ソリューションフォルダ)
?Debug
?MFCApplication1(プロジェクトフォルダ)
?MFCApplication2(プロジェクトフォルダ)
?Release
?MFCApplication1.sln
3.コントロールを追加
MFCApplication1
MFCApplication2
4.メンバ変数を追加
MFCApplication1
IDC_EDIT1:
MFCApplication2
IDC_LIST1:
5.MFCApplication2にイベントを追加
WM_TIMER(タイマーイベントでメッセージを受信)
WM_DESTROY(画面終了イベントでメールスロットとタイマー停止)
5.ソースを追加
MFCApplication1(クライアント「送信」側アプリ)
MFCApplication1Dlg.h
BOOL CMFCApplication1Dlg::OnInitDialog()
MFCApplication2(サーバ「受信」側アプリ)
よろしければポチッと押してください
]]>
(1)ピクチャーボックスに直接絵をかきます
(2)ピクチャーボックスに任意の画像を表示します
(2)-1.画像を表示する際にピクチャーボックスのサイズに伸縮します
(2)-2.伸縮画像が劣化しないように伸縮モードを指定します
<実行イメージ>
上はピクチャーボックスに直接グラデーションを描画
下はJPEGをピクチャーボックスに表示(伸縮して表示)
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.MFCのダイアログベースアプリケーションを作成します
※サンプルではプロジェクト名をPictureTestとします
2.リソースファイル(PictureTest.rc)を開いて"言語 17、"を""LANGUAGE 17,"に修正
3.ダイアログにコントロールを追加
・ピクチャーボックス:IDC_PICTURE1/IDC_PICTURE2
・ボタンはIDOKをそのまま使用
4.ピクチャーボックスにメンバ変数を追加
・IDC_PICTURE1 : m_Picture1(コントロール変数)
・IDC_PICTURE2 : m_Picture2(コントロール変数)
5.メンバ関数setPictureControl()を追加
6.ONOKのボタン押下イベント追加
7.ソースを追加
PictureTestDlg.h
PictureTestDlg.cpp
BOOL CPictureTestDlg::OnInitDialog()
{
//~~省略~~
//ピクチャーコントロールの幅と高さを取得
m_Picture1.GetWindowRect(&rect1);
m_Picture2.GetWindowRect(&rect2);
//~~省略~~
}
よろしければポチッと押してください
Visual Studio2017のダイアログベースでリソースを編集するとビルドエラーとなる
(英語版では発生しないが日本語版では発生する)
RC2135 file not found
再現手順は以下の通り
1.Visual Stuido2017でダイアログベースアプリのプロジェクト作成
2.ダイアログにエディットボックスなどを追加
3.ビルドするとエラーとなる
ちょっとはまったので、私の環境で行ったことをメモとして残します
Visual Stuido2017も最初は大丈夫だった気がする、、、
アップデートでしこまれたバグだと思われますが早く修正してほしい!!!
<バージョン>
Visual Studio Community 2017
Version 15.5.6
<ダイアログアプリ作成方法>
行ったこと
(1)MFC と ATL のサポート(x86 と x64)をインストール
Visual Studioメニューの[ツール]→[ツールと機能を取得]または
WindowsメニューのVisual Studio Installerを選択
(2)新規プロジェクトを作成
(4)アプリケーションの種類でダイアログベースを選択して[完了]押下
(5)リソースファイル(.rc)を開く
本サンプルではMFCApplication1.rcを右クリックしたコンテキストメニューで
[コードの表示]を選択
修正前)"言語 17、1¥r¥n"
修正後)"LANGUAGE 17,1¥r¥n"
<確認方法>
(1)ダイアログに確認用のGUIを追加
(2)ヘッダファイルにメンバ変数とイベント追加
本サンプルではMFCApplication1Dlg.hに追加
public:
afx_msg void OnBnClickedCheck1();
afx_msg void OnBnClickedButton1();
private:
CButton *cbtn;
CButton *ccheck;
CEdit *cedit;
(3)処理を追加
本サンプルではMFCApplication1Dlg.cppに追加
BOOL CMFCApplication1Dlg::OnInitDialog()
{
//~~ 省略 ~~
//初期化
cbtn = (CButton*)GetDlgItem(IDC_BUTTON1);
ccheck = (CButton*)GetDlgItem(IDC_CHECK1);
cedit = (CEdit*)GetDlgItem(IDC_EDIT1);
cbtn->SetWindowText(L"メッセージ表示");
ccheck->SetCheck(FALSE);
cedit->SetWindowText(L"");
//~~ 省略 ~~
}
//チェックON/OFF
void CMFCApplication1Dlg::OnBnClickedCheck1()
{
if (ccheck->GetCheck()) {
cedit->SetWindowText(L"チェックはONです");
}
else {
cedit->SetWindowText(L"チェックはOFFです");
}
}
//ボタン押下
void CMFCApplication1Dlg::OnBnClickedButton1()
{
AfxMessageBox(L"VisualStudio2017 MFCダイアログアプリケーション");
}
(4)ビルドして実行
よろしければポチッと押してください
]]>
(1)コモンダイアログ(印刷)を表示します
(2)デバイスコンテキストに文字を線を描画して帳票を生成します
(StartDoc→StartPage→EndPage→EndDoc)
(3)サンプルとして領収書を作成します
<イメージ>
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
Win32アプリケーションを作成します
1.Windowsデスクトップを選択
2.アプリケーションの種類で「コンソールアプリケーション」を選択
3.共通ヘッダの「MFC」にチェック
4.ソースを追加
よろしければポチッと押してください
・テスト用のバイナリファイルを出力します
・位置を指定してファイルに書き込みを行います
(Putステートメント)
・Seekで位置を指定してファイルから読み込みを行います
(Getステートメント)
<動作検証>
Microsoft Office 2016
<実行イメージ>
指定位置(1062バイト目/1077バイト)から書き込みを実施
全角8文字(16バイト)を書き込み
先頭から37バイト目から全角26文字を読み込み
<使い方>
適当なところにソースを貼り付けてください
バイナリファイルを読み書き() を実行すると処理を開始します
(1)AfxBeginThreadを使用したマルチスレッドサンプルです
(2)セマフォ(CSemaphoreクラス)を使って排他制御します
(3)public変数 count を5スレッドからカウントアップします
※1スレッドあたり100カウントアップするためcount=500となります
(排他制御(CSingleLock::Lock/Unlock)がないとcount<500)
<イメージ>
排他制御実装前の結果は、100カウントアップするスレッドを5つ起動してcount=500になりません
セマフォを使ってcountをいずれか1スレッドからしか使えないように排他制御(CSingleLock::Lock/Unlock)するとcount=500となりました
<使い方>
1.ダイアログベースでThreadSample2プロジェクトを作成
2.エディットボックスとボタンを配置
よろしければポチッと押してください
(1)AfxBeginThreadを使用したマルチスレッドサンプルです
(2)マルチスレッドでカウントアップ処理を行います
(3)バックグラウンドプログラムの中断、再開ができます
中断:ResumeThread
再開:SuspendThread
(4)バックグラウンド処理が終了を通知します
(5)ダイアログは終了通知を受け取り終了処理をします
<イメージ>
スレッド開始 ボタン押下によりカウントアップを開始
中断 ボタン押下により中断します(中断→再開に変更)
処理が終了したらユーザ定義メッセージで通知します
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
1.ダイアログベースでThreadSampleプロジェクトを作成
2.エディットボックスとボタンを配置
IDC_EDIT : ReadOnly=TRUE
3.コントロール変数を追加
IDC_EDIT : m_EdtCount(種類EDIT/カテゴリControl)
IDC_BTNST : m_BtnStart(種類BUTTON)
IDC_BTNSTOP : m_BtnStop(種類BUTTON)
IDOK : m_BtnOk(種類BUTTON)
4.終了通知イベントハンドラ追加
カスタムWindowsメッセージ : WM_MYMSG
メッセージハンドラ名 : OnMyMsg
5.ソースを追加
ThreadSampleDlg.h
class CThreadSampleDlg : public CDialogEx
{
//〜〜省略〜〜
ThreadSampleDlg.cpp
よろしければポチッと押してください
フォルダ選択ダイアログを表示します。
下記プロパティを設定します。
・初期表示フォルダ
・ダイアログタイトル
・ボタンのキャプション
<動作検証>
Microsoft Office 2016
<実行イメージ>
<使い方>
適当なところにソースを貼り付けてください
フォルダを選択する() を実行すると処理を開始します
'/********************************************************
'/* フォルダ選択ダイアログを表示する
'/* 引数:
'/* strDefault 初期表示フォルダ
'/* 戻り値:
'/* 選択されたときtrue、キャンセルされたときfalse
'/* strSelect 選択されたフォルダパス(参照)
'/********************************************************
Function SelectFolder(ByVal strDefault As String, _
ByRef strSelect As String) As Boolean
SelectFolder = False
strSelect = ""
'//フォルダ選択ダイアログを表示
With Application.FileDialog(msoFileDialogFolderPicker)
'初期表示フォルダ
.InitialFileName = strDefault & "¥"
'タイトルを指定
.Title = "フォルダ選択ダイアログサンプル"
'ボタンのキャプションを変更
.ButtonName = "選択確定"
'フォルダが選択された
If .Show = True Then
strSelect = .SelectedItems(1)
SelectFolder = True
Else
.Execute
End If
End With
End Function
'/********************************************************
'/* フォルダ選択ダイアログ呼び出しサンプル
'/********************************************************
Public Sub フォルダを選択する()
Dim strSelect As String
Dim wksel As Variant, wkmsg As String
'//フォルダを選択する
If Not SelectFolder(ThisWorkbook.Path, strSelect) Then
MsgBox "フォルダ選択がキャンセルされました", vbCritical
Exit Sub
End If
'//選択されたフォルダを表示
MsgBox "選択フォルダ:" & vbCrLf & strSelect, vbInformation
End Sub
よろしければポチッと押してください
]]>
(1)単一ファイル選択ダイアログを表示
(2)複数ファイル選択ダイアログを表示
<動作検証>
Microsoft Office 2016
<実行イメージ>
設定は
・ダイアログタイトル
・単一ファイル/複数ファイル選択
・ファイルフィルター(txtまたはcsv)
・初期表示フォルダ
(エクセルブックと同じフォルダを指定)
複数ファイル選択結果を表示したところ
<使い方>
適当なところにソースを貼り付けてください
ファイルを選択する() を実行すると処理を開始します
'/********************************************************
'/* ファイル選択ダイアログ(単一/複数ファイル選択)を表示する
'/* 引数:
'/* strDefault 初期表示フォルダ
'/* isMulti trueのとき複数ファイル選択可能
'/* 戻り値:
'/* 選択されたときtrue、キャンセルされたときfalse
'/* strSelect 選択されたファイルフルパス(参照)
'/********************************************************
Function SelectFile(ByVal strDefault As String, _
ByVal isMulti As Boolean, _
ByRef strSelect() As String) As Boolean
Dim sItem As Variant
SelectFile = False
ReDim strSelect(0)
strSelect(0) = ""
'//ファイル選択ダイアログを表示
'//DialogTypeは以下の通りです(詳細はMSDN参照)
'//msoFileDialogFilePicker ファイルの参照
'//msoFileDialogFolderPicker フォルダの参照
'//msoFileDialogOpen ファイルを開く
'//msoFileDialogSaveAs 名前を付けて保存
With Application.FileDialog(msoFileDialogFilePicker)
'複数選択不可(単一/複数ファイル選択)
.AllowMultiSelect = isMulti
'初期表示フォルダ
.InitialFileName = strDefault & "¥"
'ファイルフィルター(txt/csvフィルターを一番上に表示)
.Filters.Add "テキストファイル", "*.txt;*.csv", 1
'エクセルファイル選択のとき
'.Filters.Add "MSエクセルファイル", "*.xls*", 1
'タイトルを指定
.Title = "ファイル選択ダイアログサンプル"
'ファイルが選択された
If .Show = True Then
For Each sItem In .SelectedItems
If strSelect(0) <> "" Then
'配列を拡張
ReDim Preserve strSelect(UBound(strSelect) + 1)
End If
strSelect(UBound(strSelect)) = sItem
SelectFile = True
Next sItem
Else
.Execute
End If
End With
End Function
'/********************************************************
'/* ファイル選択ダイアログ呼び出しサンプル
'/********************************************************
Public Sub ファイルを選択する()
Dim strSelect() As String
Dim wksel As Variant, wkmsg As String
'//(1)単一ファイルを選択する
If Not SelectFile(ThisWorkbook.Path, False, strSelect()) Then
MsgBox "ファイル選択がキャンセルされました", vbCritical
GoTo multiselect
End If
'//選択された単一ファイルを表示
MsgBox "選択ファイル:" & vbCrLf & strSelect(0), vbInformation
multiselect:
'//(2)複数ファイルを選択する
If Not SelectFile(ThisWorkbook.Path, True, strSelect()) Then
MsgBox "ファイル選択がキャンセルされました", vbCritical
Exit Sub
End If
'//選択された複数ファイルを表示
wkmsg = ""
For Each wksel In strSelect
wkmsg = wkmsg & vbCrLf & wksel
Next wksel
MsgBox "選択ファイル:" & wkmsg, vbInformation
End Sub
よろしければポチッと押してください
]]>
(1)セルを使ってバーコード(CODE39規格)を作成します
※チェックディジットを付加します
(2)バーコード作成データは設定ファイルから読み込みます
(3)設定ファイルをデモ用に自動生成します
(4)セルを使って作成したバーコードをファイルに出力します
※画像保存がうまくいかない場合はデバッグモードでブレイクするとうまくいくことが多いです
(原因調査中)
<動作検証>
Microsoft Office 2016
<実行イメージ>
セルを使ってバーコード(CODE39)を作成
画像(JPG)として出力します
<補足>
CODE39のパターン定義は以下のように行いました
・合計9個の文字で塗りとスペースを表現
(例)「A」だと 100001001
・塗りとスペースは交互に出現(CODE39規格)
・太いバーを1、細いバーを0で表現する
・対象文字は「1-0,A-Z,-.$/+%」と半角スペースと「*」
セルにバーコードを描画するルールを以下のように行いました
・細エレメント幅は1セル分
・太エレメント幅は2セル分(エレメント比=2.0)
※9本のうち、3本は太線なので1文字12セルとなります
・キャラクタギャップは1セル分
・クワイエットゾーン(左右余白)は1文字分+αで15セル
・チェックディジットを付加
<使い方>
適当なところにソースを貼り付けてください
Code39バーコード作成() を実行すると処理を開始します
'//バーコードの高さ
Const D_BARHEIGHT As Integer = 25
'//バーコードの上余白
Const D_BARMARGIN_UP As Integer = 10
'//バーコードの下余白
Const D_BARMARGIN_DOWN As Integer = 50
'//バーコードの左余白(出力位置)
Const D_BARMARGIN_LEFT As Integer = 100
'/********************************************************
'/* Code39バーコード作成
'/********************************************************
Sub Code39バーコード作成()
Dim strCode() As String
Dim strDemotxt As String
Dim folPath As String
'//デモ用キャラクタ設定ファイルを自動生成
strDemotxt = ThisWorkbook.Path & "¥バーコード変換対象.txt"
MakeSampleTxt strDemotxt
'//デモ用キャラクタ設定ファイルから変換対象キャラクタを取得
ReadSampleTxt strDemotxt, strCode
'//先頭にシートを追加
strday = Now
ThisWorkbook.Worksheets.Add Before:=Worksheets(1)
Sheets(1).Name = "Code39_" & Format(strday, "yyyymmddhhmmss")
'//全て(数式、文字列、書式、コメント、アウトライン)クリア
Cells.Select
Selection.Clear
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 30
Selection.ColumnWidth = 0.5
Selection.RowHeight = 6
Range("A1").Select
With ActiveWindow
'//ズーム設定
.Zoom = 40
'//枠線を非表示
.DisplayGridlines = False
End With
'//画像保存用ディレクトリを作成
folPath = ThisWorkbook.Path & "¥" & Sheets(1).Name
MkDir folPath
If Dir(folPath, vbDirectory) = "" Then
MsgBox "画像保存フォルダの作成に失敗しました" & vbCrLf & folPath, vbCritical
Exit Sub
End If
'//バーコード作成メイン処理
MakeCode39BarCode strCode, folPath
'//印刷の向き(横:xlLandscape 縦:xlPortrait)
ActiveSheet.PageSetup.Orientation = xlPortrait
Range("A1").Select
'//終了メッセージ
MsgBox "おわりました", vbInformation
End Sub
'/********************************************************
'/* Code39バーコード作成 メイン処理
'/********************************************************
Sub MakeCode39BarCode(ByRef strCode() As String, ByVal folPath As String)
Dim i As Integer, j As Integer, k As Integer
Dim strptn As String, chk As String, strmoji As String
Dim gyo As Long
Dim clm As Integer
Dim wkmoji As String
'//初回の上余白を設定
gyo = D_BARMARGIN_UP
For i = 0 To UBound(strCode)
'//描画ルール
'//(1)細エレメント幅は1セル分
'//(2)太エレメント幅は2セル分(エレメント比=2.0)
'//(3)キャラクタギャップは1セル分
'//(4)クワイエットゾーン(左右余白)は1文字分+αで15セル
clm = D_BARMARGIN_LEFT
'//クワイエットゾーン分あける
clm = clm + 15
'//チェックディジットを取得
chk = GetCheckDigit(strCode(i))
If chk = "" Then
MsgBox "チェックディジットの取得に失敗しました" & vbCrLf & strCode(i), vbCritical
GoTo nextrec
End If
'//スタートコード・ストップコード、チェックディジットを付加
strmoji = "*" & strCode(i) & chk & "*"
For j = 1 To Len(strmoji)
'//パターンを取得
strptn = GetCode39BarCodePattern(Mid(strmoji, j, 1))
If strptn = "" Then
MsgBox "バーコードのパターンが見つかりませんでした" & vbCrLf & strCode(i), vbCritical
Cells(gyo, clm) = "【Error!!】"
GoTo nextrec
End If
'//描画開始
For k = 1 To 9
wkmoji = Mid(strptn, k, 1)
If 1 = (k Mod 2) Then
'//奇数の時はバー(塗り部分)
Range(Cells(gyo, clm), Cells(gyo + D_BARHEIGHT, clm + CInt(wkmoji))).Interior.Color = RGB(0, 0, 0)
Else
'//偶数の時はスペース(空白)
End If
'//カラム位置を進める
clm = clm + (1 + CInt(wkmoji))
Next
'//最終文字でなければキャラクタギャップを入れる
If j <> Len(strmoji) Then
clm = clm + 1
End If
Next
'//クワイエットゾーン分あける
clm = clm + 15
'//データを表示
With Range(Cells(gyo + D_BARHEIGHT, D_BARMARGIN_LEFT), Cells(gyo + D_BARHEIGHT + 8, clm - 1))
.Merge
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
'//マイナス(-)、スラッシュ(/)が含まれる場合の文字化け防止
.NumberFormatLocal = "@"
.Value = strCode(i)
End With
'//画像として保存
Dim savePath As String
Dim rg As Range, cht As ChartObject
savePath = folPath & "¥img" & Format(CStr(i + 1), "0000") & ".jpg"
Range(Cells(gyo, D_BARMARGIN_LEFT), Cells(gyo + D_BARHEIGHT + 8, clm - 1)).Select
Set rg = Selection
rg.CopyPicture appearance:=xlScreen, Format:=xlBitmap
Set cht = ActiveSheet.ChartObjects.Add(rg.Left, rg.Top, rg.Width, rg.Height)
cht.Activate
cht.Chart.Paste
cht.Parent.Activate
ActiveChart.ChartArea.Format.Line.Visible = False
ActiveChart.HasLegend = False
cht.Chart.Export Filename:=savePath, Filtername:="JPG"
cht.Chart.Parent.Delete
Range("A" & CStr(gyo)).Select
'//行の開始位置を更新(バーコードの高さ+データ表示)
gyo = gyo + D_BARHEIGHT + 8
'//下余白を設定
gyo = gyo + D_BARMARGIN_DOWN
'//改ページ(水平方向)を設定
ActiveSheet.HPageBreaks.Add Before:=Range("A" & CStr(gyo))
'//次のバーコードの上余白を確保
gyo = gyo + D_BARMARGIN_UP
nextrec:
Next
End Sub
'/********************************************************
'/* Code39バーコード作成 指定文字のパターンを取得
'/********************************************************
Function GetCode39BarCodePattern(ByVal moji As String) As String
GetCode39BarCodePattern = ""
Dim ptn As Variant
Dim i As Integer, wkstr() As String
'//Code39のパターン定義
'//(1)バー(塗り部分)とスペース(空白)の合計は9
'//(2)バーとスペースが交互に出現する
'//(3)太:1、細:0で表現する
'//(4)対象文字「1-0,A-Z,-.$/+%」、半角スペース、*
ptn = Array("0,000110100", "1,100100001", "2,001100001", _
"3,101100000", "4,000110001", "5,100110000", _
"6,001110000", "7,000100101", "8,100100100", _
"9,001100100", "A,100001001", "B,001001001", _
"C,101001000", "D,000011001", "E,100011000", _
"F,001011000", "G,000001101", "H,100001100", _
"I,001001100", "J,000011100", "K,100000011", _
"L,001000011", "M,101000010", "N,000010011", _
"O,100010010", "P,001010010", "Q,000000111", _
"R,100000110", "S,001000110", "T,000010110", _
"U,110000001", "V,011000001", "W,111000000", _
"X,010010001", "Y,110010000", "Z,011010000", _
"-,010000101", ".,110000100", " ,011000100", _
"$,010101000", "/,010100010", "+,010001010", _
"%,000101010", "*,010010100")
'//パターンを検索
For i = 0 To UBound(ptn)
wkstr = Split(ptn(i), ",")
If moji = wkstr(0) Then
If UBound(wkstr) = 0 Then Exit Function
GetCode39BarCodePattern = wkstr(1)
Exit Function
End If
Next
End Function
'/********************************************************
'/* Code39バーコード作成 チェックディジットを取得
'/********************************************************
Function GetCheckDigit(ByVal str As String)
GetCheckDigit = ""
Dim i As Integer
Dim wkmoji As String, iwk As Integer, ichk As Integer
Dim total As Integer
total = 0
For i = 1 To Len(str)
wkmoji = Mid(str, i, 1)
iwk = Asc(wkmoji)
If iwk >= 48 And iwk <= 57 Then
'//数値はそのまま足す
total = total + (iwk - 48)
ElseIf iwk >= 65 And iwk <= 90 Then
'//A-Zは10-35に変換して足す
total = total + (iwk - 55)
Else
'//特殊記号
Select Case iwk
Case 45 '"-"
total = total + 36
Case 46 '"."
total = total + 37
Case 32 '半角スペース
total = total + 38
Case 36 '"$"
total = total + 39
Case 47 '"/"
total = total + 40
Case 43 '"+"
total = total + 41
Case 37 '"%"
total = total + 42
Case Else
Exit Function
End Select
End If
Next
'//モジュラス43方式なので43で割った余りを求める
ichk = total Mod 43
'//チェックディジットを取得
If ichk >= 0 And ichk <= 9 Then
GetCheckDigit = CStr(ichk)
ElseIf ichk >= 10 And ichk <= 35 Then
GetCheckDigit = Chr(65 + (ichk - 10))
Else
'//特殊記号
Select Case ichk
Case 36
GetCheckDigit = "-"
Case 37
GetCheckDigit = "."
Case 38
GetCheckDigit = " "
Case 39
GetCheckDigit = "$"
Case 40
GetCheckDigit = "/"
Case 41
GetCheckDigit = "+"
Case 42
GetCheckDigit = "%"
Case Else
Exit Function
End Select
End If
End Function
'/********************************************************
'/* 取得文字列がCode39対象文字かチェック
'/* 戻り値;True(対象) False(非対象文字が混入)
'/********************************************************
Function isCode39Character(ByVal buf As String) As Boolean
Const strchk As String = "[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.$/+% ,-]"
Dim i As Integer, moji As String
'//本サンプルプログラムの仕様として32文字を上限とする
If LenB(buf) > 32 Then
isCode39Character = False
Exit Function
End If
isCode39Character = True
For i = 1 To Len(buf)
moji = Mid(buf, i, 1)
If moji Like strchk Then
'パターンにマッチ
Else
'パターンにアンマッチ
isCode39Character = False
Exit Function
End If
Next
End Function
'/********************************************************
'/* デモ用ファイルからバーコード変換対象キャラクタを取得
'/********************************************************
Sub ReadSampleTxt(ByVal strSample As String, ByRef strCode() As String)
Dim fl As Long
'//取得バッファを初期化
ReDim strCode(0)
strCode(0) = ""
'//テスト用サンプルテキストファイルをオープン
fl = FreeFile
Open strSample For Input As #fl
Do Until EOF(fl)
Line Input #fl, buf
'//大文字に変換
buf = UCase(buf)
'//半角に変換
buf = StrConv(buf, vbNarrow)
'//空白行、"'"で始まる行はスキップ
If buf = "" Then GoTo nextgyo
If Mid(buf, 1, 1) = "'" Then GoTo nextgyo
'//対象文字列意外が設定されていればスキップ
If Not isCode39Character(buf) Then GoTo nextgyo
'//バーコード変換対象文字列としてバッファにセット
If strCode(0) = "" Then
strCode(0) = buf
Else
ReDim Preserve strCode(UBound(strCode) + 1)
strCode(UBound(strCode)) = buf
End If
nextgyo:
Loop
'//テスト用サンプルテキストファイルをクローズ
Close #fl
End Sub
'/********************************************************
'/* バーコード変換対象キャラクタ設定ファイルをダミーで作成
'/********************************************************
Sub MakeSampleTxt(ByVal strSample As String)
Dim fl As Long
'//テスト用サンプルテキストファイルをオープン
fl = FreeFile
Open strSample For Output As #fl
'//データを書き込み
Print #fl, "'//// テスト用ダミーテキストファイル"
Print #fl, "1234567890"
Print #fl, "123456"
Print #fl, "123"
Print #fl, "abcdefghijklmnopqrstuvwxyz"
Print #fl, "ABC-12345/DEF"
Print #fl, "-.$/+ %"
'//テスト用サンプルテキストファイルをクローズ
Close #fl
End Sub
よろしければポチッと押してください
]]>
・プログレスバーをDLL(共通部品)として実装します
(モードレスダイアログとして実装します)
・呼び出し側(親ダイアログ)のボタン押下によりDLL(子ダイアログ)を表示します
・[中断]ボタン押下によりプログレスバーを中止できます
(親ダイアログにユーザ定義メッセージをSendMessageします)
<イメージ>
親ダイアログ(ProgressCall.exe)
ボタン押下によりプログレスバーを表示します
[中断]ボタン押下により中断確認メッセージを表示します
<動作検証&開発環境>
Visual Studio Community 2015
<使い方>
1.DLLの作成
(1)ProgressSampleプロジェクトを作成します
MFC DLLを選択してください
(2)ProgressSampleプロジェクトのプリプロセッサを定義
C/C++ → プリプロセッサ → プリプロセッサの定義 に
PROGRESSSAMPLE_EXPORTSを定義してください。
(Debug構成/Release構成とも)
(3)ダイアログをプロジェクトに追加
(4)プログレスコントロールとボタンを配置
ダイアログ:IDD_DIALOG1
プログレスコントロール:IDC_PROGRESS1
中断ボタン:IDC_BUTTON1
(5)CDialogを基底クラスとしてクラスを追加
クラス名をCProgressSampleDlgとしてください。
(6)メンバ変数を追加
プログレスコントロールのメンバ変数
名前:m_Prog
種類:CProgressCtrl
カテゴリ:Control(コントロール変数にチェック)
中断ボタンのメンバ変数
名前:m_Btn
種類:CButton
カテゴリ:Control(コントロール変数にチェック)
(7)CProgressSampleDlgクラスに仮想関数をオーバーライド
PostNcDestroy
OnInitDialog
※中断ボタン押下イベントハンドラはソースを参照してください
(8)ProgressSampleAPI.h を追加
(9)下記を参考にソースを実装
//////ProgressSampleAPI.h
#pragma once
#ifdef PROGRESSSAMPLE_EXPORTS
#define DLL_API __declspec( dllexport )
#else
#define DLL_API __declspec( dllimport )
#endif
//[中断]ボタン押下メッセージ
#define UM_PROGRESS WM_USER + 100
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
//エクスポート
//プログレスバーを初期化
DLL_API HWND InitProgressBar(HWND myWnd,int iMin, int iMax, wchar_t* cTitle);
//プログレスバーダイアログを破棄
DLL_API void CloseProgressBar(HWND childWnd);
//プログレスバーを進める
DLL_API void MoveProgressBar(HWND childWnd, int iVal);
#ifdef __cplusplus
}
#endif
//////ProgressSample.h
// ProgressSample.h : ProgressSample.DLL のメイン ヘッダー ファイル
//
#pragma once
#ifndef __AFXWIN_H__
#error "PCH に対してこのファイルをインクルードする前に 'stdafx.h' をインクルードしてください"
#endif
#include "resource.h" // メイン シンボル
// CProgressSampleApp
// このクラスの実装に関しては ProgressSample.cpp を参照してください。
//
class CProgressSampleApp : public CWinApp
{
public:
CProgressSampleApp();
// オーバーライド
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
//////ProgressSample.cpp
// ProgressSample.cpp : DLL の初期化ルーチンです。
//
#include "stdafx.h"
#include "ProgressSample.h"
#include "ProgressSampleAPI.h"
#include "ProgressSampleDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: この DLL が MFC DLL に対して動的にリンクされる場合、
// MFC 内で呼び出されるこの DLL からエクスポートされたどの関数も
// 関数の最初に追加される AFX_MANAGE_STATE マクロを
// 持たなければなりません。
//
// 例:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 通常関数の本体はこの位置にあります
// }
//
// このマクロが各関数に含まれていること、MFC 内の
// どの呼び出しより優先することは非常に重要です。
// これは関数内の最初のステートメントでなければな
// らないことを意味します、コンストラクターが MFC
// DLL 内への呼び出しを行う可能性があるので、オブ
// ジェクト変数の宣言よりも前でなければなりません。
//
// 詳細については MFC テクニカル ノート 33 および
// 58 を参照してください。
//
// CProgressSampleApp
BEGIN_MESSAGE_MAP(CProgressSampleApp, CWinApp)
END_MESSAGE_MAP()
// CProgressSampleApp コンストラクション
CProgressSampleApp::CProgressSampleApp()
{
// TODO: この位置に構築用コードを追加してください。
// ここに InitInstance 中の重要な初期化処理をすべて記述してください。
}
// 唯一の CProgressSampleApp オブジェクトです。
CProgressSampleApp theApp;
// CProgressSampleApp 初期化
BOOL CProgressSampleApp::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
/*************************************************
関数名 InitProgressBar
機能 プログレスバーを初期化
*************************************************/
DLL_API HWND InitProgressBar(HWND myWnd,int iMin, int iMax, wchar_t* cTitle)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CProgressSampleDlg *mydlg = new CProgressSampleDlg();
mydlg->m_iMin = iMin;
mydlg->m_iMax = iMax;
mydlg->m_csCap = cTitle;
mydlg->m_oyaHwnd = myWnd;
//モードレスダイアログを作成
mydlg->Create(IDD_DIALOG1);
mydlg->ShowWindow(SW_SHOW);
return mydlg->m_hWnd;
}
/*************************************************
関数名 CloseProgressBar
機能 プログレスバーダイアログを破棄
*************************************************/
DLL_API void CloseProgressBar(HWND childWnd)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CWnd* wkdlg = CWnd::FromHandle(childWnd);
((CProgressSampleDlg*)wkdlg)->DestroyWindow();
}
/*************************************************
関数名 MoveProgressBar
機能 プログレスバーを進める
*************************************************/
DLL_API void MoveProgressBar(HWND childWnd,int iVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
int iMin, iMax;
CWnd* wkdlg = CWnd::FromHandle(childWnd);
((CProgressSampleDlg*)wkdlg)->m_Prog.SetPos(iVal);
//プログレスバーが最後まで進んでいたらボタンキャプション変更
((CProgressSampleDlg*)wkdlg)->m_Prog.GetRange(iMin, iMax);
if (iVal == iMax) {
((CProgressSampleDlg*)wkdlg)->m_Btn.SetWindowText(_T("閉じる"));
}
}
//////ProgressSampleDlg.h
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
// CProgressSampleDlg ダイアログ
class CProgressSampleDlg : public CDialog
{
DECLARE_DYNAMIC(CProgressSampleDlg)
public:
CProgressSampleDlg(CWnd* pParent = NULL); // 標準コンストラクター
virtual ~CProgressSampleDlg();
int m_iMin;
int m_iMax;
CString m_csCap;
//[中断]ボタン押下時にSeneMessageする
HWND m_oyaHwnd;
// ダイアログ データ
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート
DECLARE_MESSAGE_MAP()
public:
CProgressCtrl m_Prog;
CButton m_Btn;
virtual BOOL OnInitDialog();
virtual void PostNcDestroy();
afx_msg void OnBnClickedButton1();
};
//////ProgressSampleDlg.cpp
// ProgressSampleDlg.cpp : 実装ファイル
//
#include "stdafx.h"
#include "ProgressSample.h"
#include "ProgressSampleDlg.h"
#include "ProgressSampleAPI.h"
#include "afxdialogex.h"
#include <Windows.h>
// CProgressSampleDlg ダイアログ
IMPLEMENT_DYNAMIC(CProgressSampleDlg, CDialog)
CProgressSampleDlg::CProgressSampleDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_DIALOG1, pParent)
{
}
CProgressSampleDlg::~CProgressSampleDlg()
{
}
void CProgressSampleDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS1, m_Prog);
DDX_Control(pDX, IDC_BUTTON1, m_Btn);
}
BEGIN_MESSAGE_MAP(CProgressSampleDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &CProgressSampleDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// CProgressSampleDlg メッセージ ハンドラー
/*************************************************
関数名 OnInitDialog
機能 ダイアログの初期化
*************************************************/
BOOL CProgressSampleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_Prog.SetRange(m_iMin, m_iMax);
SetWindowText(m_csCap);
//閉じる[X]ボタンを無効(グレーアウト)
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->EnableMenuItem(SC_CLOSE, MF_GRAYED);
return TRUE;
}
/*************************************************
関数名 PostNcDestroy
機能 ダイアログの破棄
*************************************************/
void CProgressSampleDlg::PostNcDestroy()
{
delete this;
CDialog::PostNcDestroy();
}
/*************************************************
関数名 OnBnClickedButton1
機能 [中 断]ボタン押下イベントハンドラ
*************************************************/
void CProgressSampleDlg::OnBnClickedButton1()
{
//ユーザー定義メッセージを送信
CWnd::FromHandle(m_oyaHwnd)->SendMessage(UM_PROGRESS, (WPARAM)NULL, (LPARAM)NULL);
}
2.呼び出し側(親ダイアログ)の作成
(1)同一ソリューション内にProgressCallプロジェクトを作成します
ダイアログベースで作成してください。
(2)プロジェクトの依存関係を設定(ビルド順も同時設定できます)
ProgressCallプロジェクトの依存先であるProgressSampleプロジェクトにチェックON
(3)IDOKボタン、IDCANCELボタンをそのまま使います
ダイアログ:IDD_PROGRESSCALL_DIALOG
呼び出しボタン:IDOK
終了ボタン:IDCANCEL
(4)リンカー設定
ProgressCallプロパティページにて下記を設定
リンカー → 全般 → 追加のライブラリディレクトリ に
Debug構成: ..¥Debug
Release構成: ..¥Release
リンカー → 全般 → 入力 に
Debug構成/Release構成とも: ProgressSample.lib
(5)下記を参考にソースを実装
//////ProgressCallDlg.h
// ProgressCallDlg.h : ヘッダー ファイル
//
#pragma once
// CProgressCallDlg ダイアログ
class CProgressCallDlg : public CDialogEx
{
// コンストラクション
public:
CProgressCallDlg(CWnd* pParent = NULL); // 標準コンストラクター
// ダイアログ データ
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PROGRESSCALL_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート
// 実装
protected:
HICON m_hIcon;
// 生成された、メッセージ割り当て関数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnButtonClose(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
private:
//プログレスバーダイアログのハンドル
HWND childHWND;
BOOL m_bProgress;
HWND ShowProgress();
public:
afx_msg void OnBnClickedOk();
};
//////ProgressCallDlg.cpp
// ProgressSampleDlg.cpp : 実装ファイル
//
#include "stdafx.h"
#include "ProgressSample.h"
#include "ProgressSampleDlg.h"
#include "ProgressSampleAPI.h"
#include "afxdialogex.h"
#include <Windows.h>
// CProgressSampleDlg ダイアログ
IMPLEMENT_DYNAMIC(CProgressSampleDlg, CDialog)
CProgressSampleDlg::CProgressSampleDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_DIALOG1, pParent)
{
}
CProgressSampleDlg::~CProgressSampleDlg()
{
}
void CProgressSampleDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS1, m_Prog);
DDX_Control(pDX, IDC_BUTTON1, m_Btn);
}
BEGIN_MESSAGE_MAP(CProgressSampleDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &CProgressSampleDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// CProgressSampleDlg メッセージ ハンドラー
/*************************************************
関数名 OnInitDialog
機能 ダイアログの初期化
*************************************************/
BOOL CProgressSampleDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_Prog.SetRange(m_iMin, m_iMax);
SetWindowText(m_csCap);
//閉じる[X]ボタンを無効(グレーアウト)
CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->EnableMenuItem(SC_CLOSE, MF_GRAYED);
return TRUE;
}
/*************************************************
関数名 PostNcDestroy
機能 ダイアログの破棄
*************************************************/
void CProgressSampleDlg::PostNcDestroy()
{
delete this;
CDialog::PostNcDestroy();
}
/*************************************************
関数名 OnBnClickedButton1
機能 [中 断]ボタン押下イベントハンドラ
*************************************************/
void CProgressSampleDlg::OnBnClickedButton1()
{
//ユーザー定義メッセージを送信
CWnd::FromHandle(m_oyaHwnd)->SendMessage(UM_PROGRESS, (WPARAM)NULL, (LPARAM)NULL);
}
よろしければポチッと押してください
]]>
(1)オリジナル(独自)のプログレスバーを作成します
※ActiveXのプログレスバーは使用しません
(2)フレームの中に背景が緑のラベルを配置してWidth変更により進捗表示します
(3)透明ラベルにて進捗「999 / 999 %」を表示します
(4)キャンセル(中断)押下により処理を中断できます
<動作検証&開発環境>
Microsoft Office2016
<実行イメージ>
ユーザフォーム表示直後のイメージ
窪んだフレーム中の緑のラベルのWidthを変化させます
進捗表示ラベルは背景を透明に設定しています
キャンセル押下により中断できます
[X]ボタンや[Alt]+[F4]でも同じ動作をします
<使い方>
(1)[挿入]メニューからユーザフォームを挿入します
※名前はUserForm1(デフォルト名)とします
(2)コントロールを配置します
・Frame1
Caption : なし
Width : 400
SpecialEffect : fmSpecialEffectSunken(窪みフレーム)
・Label1
BackColor : 緑(なんでもいいです)
Caption : なし
Width : 400(フレームの中に配置)
・Label2
BackStyle : mBackStyleTransparent(背景透明)
TextAlign : fmTextAlignCenter(中央揃え)
・CommandButton1
Caption : スタート
・CommandButton2
Caption : キャンセル
(3)ソースをUserForm1に貼り付けます
'//Windows API
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const HWND_TOPMOST As Long = -1
Private Const SWP_NOSIZE As Long = &H1&
Private Const SWP_NOMOVE As Long = &H2&
'//キャンセルボタン押下判定フラグ
Public bCancel As Boolean
'//プログレスバー実行中フラグ
Public bProgress As Boolean
'/********************************************************
'/* ユーザフォームを常に前面に表示
'/********************************************************
Private Sub UserForm_Activate()
Call SetWindowPos(GetForegroundWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
'/********************************************************
'/* ユーザフォームの初期化
'/********************************************************
Private Sub UserForm_Initialize()
'//ラベルの位置を明示的に指定
'//フレーム(Frame1)とラベル(Label1)の左上座標&幅を合わせる
With Me.Label1
.Left = 0
.Top = 0
.Width = 400
.Visible = False
End With
'//ラベル2(プログレスバーの進捗表示用)初期表示
Me.Label2.Caption = "スタートボタンを押してください"
'//キャンセルボタン押下フラグ
bCancel = False
'//プログレスバー実行中フラグ
bProgress = False
End Sub
'/********************************************************
'/* [スタート]押下によりプログレスバー開始
'/********************************************************
Private Sub CommandButton1_Click()
Dim iBar As Integer
Dim strMsg As String
'//初期値セット
iBar = 0
bCancel = False
strMsg = "おわりました"
'//プログレスバー(ラベル)は最初は幅0
Me.Label1.Width = 0
Me.Label1.Visible = True
'//ラベル2(プログレスバーの進捗表示用)は0を初期表示
Me.Label2.Caption = " 0 / 100 %"
'//プログレスバー開始
bProgress = True
Do
'0-100まで
If iBar = 100 Then Exit Do
'200ミリ秒ごとにカウントアップ
'大括弧[]で囲むとSleepを使わなくてもミリ秒指定が可能です
'Application.Wait Now + TimeValue("0:00:01")
Application.Wait [Now() + "0:00:00.2"]
iBar = iBar + 1
'ラベルの幅を400としているのでカウンター×4とする
Me.Label1.Width = (iBar * 4)
'進捗表示(分子はスペース埋めで3桁固定とする)
Me.Label2.Caption = Format(CStr(iBar), "@@@") & " / 100 %"
'再描画
Me.Repaint
'キャンセルボタン押下等のイベント処理
DoEvents
If bCancel Then
If MsgBox("キャンセルしてもよろしいですか?", vbQuestion + vbYesNo) = vbYes Then
'メッセージで[はい]が押下されたらキャンセルする
strMsg = "キャンセルされました"
Exit Do
Else
'メッセージで[いいえ]が押下されたらキャンセル処理をスキップ
bCancel = False
End If
End If
Loop
'//プログレスバー終了
bProgress = False
'//終了メッセージ表示
MsgBox strMsg, vbInformation
End Sub
'/********************************************************
'/* [キャンセル]押下イベントハンドラ
'/********************************************************
Private Sub CommandButton2_Click()
'//キャンセル処理へ進む
bCancel = True
End Sub
'/********************************************************
'/* 「x」ボタンでフォームを閉じないようにする
'/********************************************************
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'//プログレスバー実行中に「x」またはAlt+F4でフォームを閉じようとしたとき
If bProgress Then
If CloseMode = vbFormControlMenu Then
'//キャンセル処理へ進む
bCancel = True
'//閉じるボタン「x」では閉じない
Cancel = True
End If
End If
End Sub
よろしければポチッと押してください
]]>
(1)画面上に長い十字線カーソルを表示します
(2)画面上をダブルクリックするとポイント座標を表示します
※サンプルのためOnLButtonDblClkで表示しています
※再描画するためにはWM_PAINTで描画する必要があります
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
画面上に十字線カーソルが表示されます
ダブルクリックするとポイント座標を表示します
<使い方>
(1)CrossCursorプロジェクトを作成
(2)シングルドキュメント(SDK)、MFC標準を選択
(3)システムメニュー以外のチェックを外す
(閉じるボタン「X」のみ表示する)
(4)本サンプルでは使用しない機能を外す
(5)クラスウィザードにてDrawCrossLineメンバ関数を追加
名前:DrawCrossLine
戻り値:void
パラメータ:CPoint cp
(6)メッセージハンドラを追加
・WM_LBUTTONDBLCLK(ダブルクリックイベント)
・WM_MOUSEMOVE(マウス移動イベント)
・WM_SETCURSOR(カーソルセット)
(7)ソースの追加
/* CrossCursorView.h */
private:
CPoint oldpo; //十字線の古いポイント位置を保持するための変数
/* CrossCursorView.cpp */
/*************************************************
関数名 DrawCrossLine
機能 カーソルのポイント位置より十字線(縦線+横線)を表示します
*************************************************/
void CCrossCursorView::DrawCrossLine(CPoint po)
{
RECT rect;
HWND hWnd = (HWND)this->GetSafeHwnd();
HDC hdc = ::GetDC(hWnd);
//描画できるクライアント領域を取得
::GetClientRect(hWnd, &rect);
//前景の描画モードを設定(色を反転させる)
//SetROP2についてはMSDNを参照してください
SetROP2(hdc, R2_NOT);
//縦線を描画
MoveToEx(hdc, po.x, 0, NULL);
LineTo(hdc, po.x, rect.bottom);
//横線を描画
MoveToEx(hdc, 0, po.y, NULL);
LineTo(hdc, rect.right, po.y);
//デバイスコンテキストを開放
::ReleaseDC(hWnd, hdc);
}
/*************************************************
関数名 OnLButtonDblClk
機能 ダブルクリックによりポイント座標を表示します
※実際の描画はWM_PAINTで行う必要があります(再描画されないため)
*************************************************/
void CCrossCursorView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
HWND hWnd = (HWND)this->GetSafeHwnd();
HDC hdc = ::GetDC(hWnd);
HPEN pen, oldpen;
//表示する文字列を生成
TCHAR tcstr[255];
ZeroMemory(&tcstr, sizeof(tcstr));
wsprintf(tcstr, L"(%d,%d)", point.x, point.y);
//緑のペン
pen = CreatePen(PS_SOLID, 5, RGB(0, 255, 0));
oldpen = (HPEN)SelectObject(hdc, pen);
//十字線を消去
DrawCrossLine(point);
//ポイント位置を中心に円を描画
Ellipse(hdc, point.x - 10, point.y - 10, point.x + 10, point.y + 10);
//ポイント位置を左上座標として文字列を描画
SetTextColor(hdc, RGB(255, 0, 0));
TextOut(hdc, point.x, point.y, tcstr, lstrlen(tcstr));
DrawCrossLine(point);
//ペンを戻す
SelectObject(hdc, oldpen);
//デバイスコンテキストを開放
::ReleaseDC(hWnd, hdc);
//ペンオブジェクトを開放
DeleteObject(pen);
}
/*************************************************
関数名 OnMouseMove
機能 マウスの動きに合わせて十字線を表示します
*************************************************/
void CCrossCursorView::OnMouseMove(UINT nFlags, CPoint point)
{
CClientDC dc(this);
//古い十字線を消去
DrawCrossLine(oldpo);
//現在位置の十字線を描画
DrawCrossLine(point);
//現在位置を保持
oldpo = point;
}
/*************************************************
関数名 OnSetCursor
機能 デフォルトのカーソルを4方向矢印(IDC_SIZEALL)に設定します
*************************************************/
BOOL CCrossCursorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
//カーソルの種類についてはMSDNを参照してください
//ウェイトカーソル
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
//ウェイトカーソル&矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_APPSTARTING));
//クロスカーソル
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
//4方向矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
//斜め左下がり矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENESW));
//斜め右下がり矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENWSE));
//上下両方向矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
//左右両方向矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
//上矢印
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_UPARROW));
//アイビーム
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM));
//禁止
//::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO));
//4方向十字カーソルを選択
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
return TRUE;
}
よろしければポチッと押してください
]]>
(1)ExportAsFixedFormatを使用してシートをPDFで出力します
※ExportAsFixedFormatの対象はOffice 2013以降です
※マクロ実行時に必ずブックをマクロ有効形式(.xlsm)で保存してください
(2)サンプルの出力対象シートを自動で生成します
※コピペのみで動作確認できます
(3)印刷範囲、ヘッダー、フッターも自動で設定します
<動作検証&開発環境>
Microsoft Office2016
<実行イメージ>
サンプルの出力対象シートを自動で生成
ExportAsFixedFormatを使用してシートをPDFで出力
<使い方>
適当なところにソースを貼り付けてください
実行前にブックをマクロ有効形式(.xlsm)で保存してください
(400、1004などの実行エラーとなります)
PDF出力メイン() を実行すると処理を開始します
'********************************************
'シートをPDFで出力するサンプルプログラム
'(1)出力対象のサンプル明細書を自動生成
'(2)印刷範囲、ヘッダー、フッターを設定
'(3)PDFファイルを出力
'※ExportAsFixedFormatの対象:Office 2013 and later
'********************************************
Public Sub PDF出力メイン()
'//描画を停止
Application.ScreenUpdating = False
'//(1)出力対象のサンプル明細書を自動生成
サンプル明細書作成
'//(2)印刷範囲、ヘッダー、フッターを設定
'//PageSetupメンバーの詳細については Office DevCenter を参照
With ActiveSheet.PageSetup
'印刷の向き(横:xlLandscape 縦:xlPortrait)
.Orientation = xlLandscape
'横1ページ×縦1ページ
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
'ヘッダーを設定
'詳細は ヘッダーとフッターに指定できる書式コード 参照
'日付と現在時刻
.RightHeader = "印刷日時:&D(&T)"
'フッターを設定
'ページ番号
.CenterFooter = "&P/&N"
'ブック名とシート名
.RightFooter = "&F(&A)"
'余白設定
'上3、左1.5、右1.5、下2、ヘッダー2、フッター1
.TopMargin = Application.CentimetersToPoints(3)
.LeftMargin = Application.CentimetersToPoints(1.5)
.RightMargin = Application.CentimetersToPoints(1.5)
.BottomMargin = Application.CentimetersToPoints(2)
.HeaderMargin = Application.CentimetersToPoints(2)
.FooterMargin = Application.CentimetersToPoints(1)
'水平方向ページ中央
.CenterHorizontally = True
End With
'//改ページプレビュー表示
ActiveWindow.View = xlPageBreakPreview
'//ズーム100%で表示
ActiveWindow.Zoom = 100
'//(3)PDFファイルを出力
'//ファイル名にF4セルの氏名をセット(スペースはトリムする)
Dim strPdf As String
strPdf = ThisWorkbook.Path & "¥Meisai_" & Replace(Replace(Range("F4").Text, " ", ""), " ", "") & Replace(Replace(Replace(Now(), "/", ""), " ", ""), ":", "") & ".pdf"
'//PDFに変換する
'//ExportAsFixedFormatメソッドの詳細については Office DevCenter を参照
ThisWorkbook.Sheets(ThisWorkbook.ActiveSheet.Index).ExportAsFixedFormat Type:=xlTypePDF, Filename:=strPdf, Quality:=xlQualityStandard
'//描画を再開
Application.ScreenUpdating = True
End Sub
'********************************************
'PDF出力対象のサンプル明細書を生成
'(1)サンプルデータをセット
'(2)帳票の体裁を自動で設定
'********************************************
Public Sub サンプル明細書作成()
Dim ar As Variant
ar = Array( _
"経費明細書,,,,,,,,", _
"サンプル株式会社 総務部,,,,,,,,", _
"〒000-0000 東京都新宿区西新宿1丁目,,,,,,,,", _
"電話,(03)9999-9999,,氏名,山田 太郎,,,,", _
"FAX,(03)9999-9998,,部署,営業部,,,,", _
"電子メール,info@abcdef.com,,職位,管理責任者,,,,", _
"Web,www.abcdef.com,,上司,鈴木 イチロウ,,,,", _
",,,,,,,,", _
"日付,勘定科目,内容,宿泊費,交通費,食費,通信費,雑費,合計", _
"43070,営業経費,旅費,44500,22500,2000,,500,69500", _
"43085,営業経費,営業会議,,13500,,,,13500", _
"43092,営業経費,営業会議,,13500,,1600,,15100", _
"合計,,,44500,49500,2000,1600,500,98100")
'//シートをクリア
ThisWorkbook.Activate
Cells.Select
Selection.Clear
Selection.ColumnWidth = 20
Selection.RowHeight = 25
Selection.Font.Name = "メイリオ"
Selection.Font.Size = 11
Selection.Borders.LineStyle = False
'//セルの折り返しを解除
Selection.WrapText = False
'//列幅調整
Columns("A").ColumnWidth = 3
'//帳票タイトル調整
With Rows("1")
.RowHeight = 40
.VerticalAlignment = xlTop
.Font.Size = 25
.Font.Bold = True
End With
'//データをシートに展開
Dim i As Integer, j As Integer
Dim wkbuf As Variant
For i = 0 To UBound(ar)
wkbuf = Split(ar(i), ",")
'不正なデータであれば次レコードへ
If UBound(wkbuf) <> 8 Then GoTo nextrec
'データを表示
For j = 0 To UBound(wkbuf)
'表示はB列からのため(j + 1)とする
Cells(i + 1, (j + 1) + 1) = wkbuf(j)
Next j
nextrec:
Next i
'//セルにインデントを設定
With Range("C4:C7,F4:F7")
.IndentLevel = 1
.Borders(xlEdgeLeft).LineStyle = xlContinuous
.Borders(xlEdgeLeft).Weight = xlThin
End With
'//表に罫線を引く
With Range("B9:J13")
.Borders.LineStyle = xlContinuous
.Borders.Weight = xlThin
End With
'//項目行を中央揃えにする
With Range("B9:J9")
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.Interior.Color = RGB(128, 128, 128)
.Font.Color = RGB(255, 255, 255)
End With
'//合計行の設定
With Range("B13:J13")
.Interior.Color = RGB(217, 217, 217)
.Font.Bold = True
End With
With Range("B13")
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
'//金額書式設定(円マーク付き、カンマ区切り)
Range("E10:J13").NumberFormatLocal = "¥#,##0; ¥-#,##0"
'//日付書式設定(YYYY年MM月DD日形式)
With Range("B10:B12")
.NumberFormatLocal = "yyyy""年""mm""月""dd""日"""
.HorizontalAlignment = xlCenter
End With
Range("A1").Select
End Sub
よろしければポチッと押してください
]]>(1)独自のメニューバー(コマンドバー)を設定します
[アドイン](メニュー)
[備忘録サンプル](オリジナル)
緑でフォームを表示
ピンクでフォームを表示
(2)コマンドバーはワークブックオープンで生成、クローズで破棄されます
(3)独自の右クリックメニュー(セル右クリックメニュー)を設定します
(4)下記メニュー機能を実装します
緑でフォームを表示(MainShow1プロシージャコール)
ピンクでフォームを表示(MainShow2プロシージャコール)
(5)フォームの表示位置を保持します
<動作検証&開発環境>
Microsoft Office2016
<実行イメージ>
アドインメニューに独自メニューを設定します
セルを右クリックすると独自メニューが表示されます
[緑でフォームを表示]をクリックするとMainShow1がコールされます
[ピンクでフォームを表示]をクリックするとMainShow2がコールされます
<使い方>
(1)[挿入]メニューからユーザフォームを挿入します
※名前はUserForm1(デフォルト名)とします
(2)[挿入]メニューから標準モジュールを挿入します
※名前はModule1(デフォルト名)とします
(3)ユーザフォーム(UserForm1)にボタンコントロールを貼り付けます
※名前はbtnClose、キャプションを「閉じる」とします
(4)ソースを貼り付けます
’ThisWorkbook(OpenとBeforeCloseイベント処理追加)
'/********************************************************
'/* ワークブックオープンでメニューバーを作成
'/********************************************************
Private Sub Workbook_Open()
Dim wkstr As String
'メニューバーの作成
Call Module1.CreateMenu
'ポップアップメニューの作成
Call Module1.CreatePopUp
'フォームの初期表示位置はエクセルアプリケーションの左上
Module1.XPOS = Application.Left
Module1.YPOS = Application.Top
'先頭シートのA1選択
ThisWorkbook.Sheets(1).Select
Range("A1").Select
End Sub
'/********************************************************
'/* ワークブッククローズでメニューバーを削除
'/********************************************************
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim objCB As CommandBar
Set objCB = Application.CommandBars("Worksheet Menu Bar")
'メニューバーが作成済みであれば削除する
On Error Resume Next
objCB.Controls(Module1.CAP_MAIN).Delete
objCB = Nothing
End Sub
’Module1(定数定義と独自メニュー生成処理を追加)
'//フォームの表示位置を保持
Public XPOS As Integer
Public YPOS As Integer
Public Const CAP_MAIN = "備忘録サンプル"
Public Const MENU1 = "緑でフォームを表示"
Public Const MENU2 = "ピンクでフォームを表示"
'/********************************************************
'/* メニューバー(アドインメニュー)の作成
'/********************************************************
Public Sub CreateMenu()
Dim objCB As CommandBar
Dim CmdCtrl As CommandBarControl
Dim CmdBtn1 As CommandBarButton, CmdBtn2 As CommandBarButton
Set objCB = Application.CommandBars("Worksheet Menu Bar")
'作成済みであれば削除
On Error Resume Next
objCB.Controls(CAP_MAIN).Delete
On Error GoTo 0
Set CmdCtrl = CommandBars("Worksheet Menu Bar").Controls.Add(Type:=msoControlPopup, Temporary:=True)
CmdCtrl.Caption = CAP_MAIN
Set CmdBtn1 = CmdCtrl.Controls.Add(Type:=msoControlButton)
CmdBtn1.Caption = MENU1
CmdBtn1.OnAction = "MainShow1"
Set CmdBtn2 = CmdCtrl.Controls.Add(Type:=msoControlButton)
CmdBtn2.Caption = MENU2
CmdBtn2.OnAction = "MainShow2"
End Sub
'/********************************************************
'/* ポップアップメニュー(右クリックメニュー)の作成
'/********************************************************
Public Sub CreatePopUp()
Dim CmdBar As CommandBar
Dim CmdBtn1 As CommandBarButton, CmdBtn2 As CommandBarButton
Set CmdBar = CommandBars("Cell")
CmdBar.Reset
Set CmdBtn1 = CmdBar.Controls.Add(msoControlButton, Temporary:=True)
CmdBtn1.BeginGroup = True
CmdBtn1.Caption = MENU1
CmdBtn1.OnAction = "MainShow1"
Set CmdBtn2 = CmdBar.Controls.Add(msoControlButton, Temporary:=True)
CmdBtn2.BeginGroup = True
CmdBtn2.Caption = MENU2
CmdBtn2.OnAction = "MainShow2"
Set CmdBar = Nothing
Set CmdBtn1 = Nothing
Set CmdBtn2 = Nothing
End Sub
'/********************************************************
'/* メニュー画面の表示
'/* MENU1からコールされた場合はMainShow1
'/* MENU2からコールされた場合はMainShow2
'/********************************************************
Public Sub MainShow1()
'フォームのキャプション変更
UserForm1.Caption = Module1.MENU1
'メニュー画面の背景色を設定
UserForm1.BackColor = RGB(169, 208, 142)
UserForm1.btnClose.BackColor = RGB(169, 208, 142)
'メニュー画面表示
UserForm1.Show vbModal
End Sub
Public Sub MainShow2()
'フォームのキャプション変更
UserForm1.Caption = Module1.MENU2
'メニュー画面の背景色を設定
UserForm1.BackColor = RGB(255, 178, 255)
UserForm1.btnClose.BackColor = RGB(255, 178, 255)
'メニュー画面表示
UserForm1.Show vbModal
End Sub
'UserForm1(表示位置の設定、Clickイベント)
'/********************************************************
'/* フォームの表示位置を指定
'/********************************************************
Private Sub UserForm_Activate()
Application.ScreenUpdating = False
Me.Left = Module1.XPOS
Me.Top = Module1.YPOS
Application.ScreenUpdating = True
End Sub
'/********************************************************
'/* [閉じる]ボタン押下時の処理
'/********************************************************
Private Sub btnClose_Click()
Unload Me
End Sub
'/********************************************************
'/* フォームを閉じるときの処理
'/********************************************************
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Module1.XPOS = Me.Left
Module1.YPOS = Me.Top
'[x]ボタンで閉じれなくする
If CloseMode = vbFormControlMenu Then
Cancel = True
End If
End Sub
よろしければポチッと押してください
]]>ブックのドキュメントプロパティ(BuiltinDocumentProperties)を設定します
(1)新規ブックにドキュメントプロパティをセット
(2)先頭シートにドキュメントプロパティの内容を出力します
<動作検証&開発環境>
Microsoft Office2016
<実行イメージ>
シートにドキュメントプロパティの内容を出力
<使い方>
適当なところにソースを貼り付けてください
新規ブックにプロパティを設定する() を実行すると処理を開始します
'********************************************
'VBAで新規ブックにプロパティを設定する
'(1)ブックを新規作成
'(2)プロパティを設定
'(3)シートにプロパティの内容を出力して保存
'********************************************
Sub 新規ブックにプロパティを設定する()
Dim strName As String
Dim gyo As Integer
'//ブック名を生成
strName = ThisWorkbook.Path & "¥SAMPLE_" & Replace(Replace(Replace(Now(), "/", ""), " ", ""), ":", "") & ".xlsx"
'//テスト用ブックを新規作成
'//FileFormatにExcelブック(*.xlsx)形式を指定
Workbooks.Add
'//ブックを保存する(ファイル形式に.xlsx:xlOpenXMLWorkbookを指定)
'//XlFileFormat列挙体の設定値についてはOffice DevCenter参照
ActiveWorkbook.SaveAs Filename:=strName, FileFormat:=xlOpenXMLWorkbook
ActiveWorkbook.Close
'//ブックにプロパティを設定
Workbooks.Open strName
With Workbooks(Mid(strName, InStrRev(strName, "¥") + 1))
'タイトル
.BuiltinDocumentProperties("Title").Value = "ブックにプロパティをセット"
'件名
.BuiltinDocumentProperties("Subject").Value = "プロパティの設定と取得のテスト"
'タグ
.BuiltinDocumentProperties("Keywords").Value = "VBA BuiltinDocumentProperties"
'分類項目
.BuiltinDocumentProperties("Category").Value = "VBAプログラムサンプル"
'コメント
.BuiltinDocumentProperties("Comments").Value = "平成28年12月会議にて使用予定" & vbCrLf & "佐藤部長レビュー済み資料(2016.11.05)"
'作成者
.BuiltinDocumentProperties("Author").Value = "山田 太郎"
'改定番号(整数)
.BuiltinDocumentProperties("Revision Number").Value = "4"
'バージョン番号
.BuiltinDocumentProperties("Document version").Value = "1.0.8"
'会社
.BuiltinDocumentProperties("Company").Value = "株式会社○△□"
'マネージャー
.BuiltinDocumentProperties("Manager").Value = "田中部長"
'コンテンツの作成日時
.BuiltinDocumentProperties("Creation Date").Value = "2016/12/20 10:09"
'//すべてのプロパティを先頭シートに出力する
.Sheets(1).Activate
'//セル幅、フォントを指定
Columns("A:B").Select
Selection.Clear
Selection.ColumnWidth = 30
Selection.RowHeight = 50
Selection.Font.Name = "メイリオ"
Selection.Font.Size = 10
'//折り返して全体を表示
Selection.WrapText = True
'//水平方向左、垂直方向中央揃え
Selection.HorizontalAlignment = xlLeft
Selection.VerticalAlignment = xlCenter
Range("A1").Select
'//エラー処理ルーチンを有効
On Error Resume Next
gyo = 1
For Each p In .BuiltinDocumentProperties
Cells(gyo, 1).Value = p.Name
Cells(gyo, 2).Value = p.Value
gyo = gyo + 1
Next
On Error GoTo 0
'//ブックをクローズ
.Close True
End With
End Sub
よろしければポチッと押してください
]]>
(1)構造体(ユーザ定義)の可変配列をCArrayを使用して実装する
(2)ユーザ定義構造体のメンバは以下の2つ
urban(都市名) char[1024]
ipopulation(人口) int
(3)下記メソッドを使用してみる
Add:要素を追加
GetAt:指定インデックスから値を返す
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
東京都の都市別人口(出典:総務省統計局)をコマンドプロンプトに出力します
<使い方>
(1)Win32コンソールアプリケーションでプロジェクトを作成
(2)[次へ]を押下し、アプリケーション設定画面の共通ヘッダーファイルを追加にて「MFC」にチェック
(3)ソースの追加
//構造体定義
typedef struct SCT_POPULATION {
char urban[1024];
int ipopulation;
}sctPopulation;
//プロトタイプ宣言
void setPopulation(CArray<sctPopulation> *sctpop);
// 唯一のアプリケーション オブジェクトです。
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: MFC の初期化ができませんでした。¥n");
nRetCode = 1;
}
else
{
//構造体可変配列を宣言
CArray <sctPopulation> sctpop;
//東京都の都市別人口を構造体可変配列にセット
setPopulation(&sctpop);
//構造体可変配列の内容をコンソールに出力
for (int i = 0; i < sctpop.GetSize(); i++)
{
printf(" %-20s %9d人¥n", sctpop.GetAt(i).urban, sctpop.GetAt(i).ipopulation);
}
//コマンドプロンプト画面が閉じないようにする
system("pause");
}
}
else
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: GetModuleHandle が失敗しました¥n");
nRetCode = 1;
}
return nRetCode;
}
/*************************************************
関数名 setPopulation
機能 可変構造体配列に東京都都市別人口データを設定
出典 総務省統計局「都市別人口」
*************************************************/
void setPopulation(CArray<sctPopulation> *sctpop)
{
CString cbuf,cdat;
sctPopulation wkpop;
sctpop->RemoveAll();
char *urbanPopulation[] = {
"千代田区,56873",
"中央区,138088",
"港区,240585",
"新宿区,327712",
"文京区,207413",
"台東区,189795",
"墨田区,258423",
"江東区,493952",
"品川区,372077",
"目黒区,269689",
"大田区,707455",
"世田谷区,874332",
"渋谷区,217008",
"中野区,316625",
"杉並区,547165",
"豊島区,275507",
"北区,338084",
"荒川区,209087",
"板橋区,544172",
"練馬区,714656",
"足立区,674111",
"葛飾区,449527",
"江戸川区,680262",
"八王子,562572",
"立川,179090",
"武蔵野,142138",
"三鷹,182092",
"青梅,137052",
"府中,254551",
"昭島,112727",
"調布,224191",
"町田,426648",
"小金井,117427",
"小平,186958",
"日野,180975",
"東村山,151412",
"国分寺,119379",
"国立,74558",
"福生,58553",
"狛江,79096",
"東大和,86162",
"清瀬,74374",
"東久留米,116494",
"武蔵村山,72092",
"多摩,147486",
"稲城,86594",
"羽村,56604",
"あきる野,81697",
"西東京,198267",
"0"
};
for (int i = 0;; i++)
{
//ループ終了条件("0"が出現したらデータセット終了)
if (strcmp(urbanPopulation[i], "0") == 0) break;
//対象インデックスの文字列を取得
cbuf = urbanPopulation[i];
//cbufの1カラム目(都市名)をセット
AfxExtractSubString(cdat, cbuf, 0, ',');
//CStringをLPCSTRへマクロを使って変換する
strcpy_s(wkpop.urban, CT2CA(cdat));
//cbufの2カラム目(人口)をセット
AfxExtractSubString(cdat, cbuf, 1, ',');
wkpop.ipopulation = atoi(CStringA(cdat));
//構造体可変配列にセット
sctpop->Add(wkpop);
}
return;
}
よろしければポチッと押してください
]]>
VBAで表の体裁を整え、即印刷できるようにシートを設定します
(1)シートを挿入しテストデータ「鮮魚の一人当たり購入数量」をセット
(2)セル幅、セル内の表示位置、罫線等をセット
(3)印刷範囲、ヘッダー、フッターをセット
<動作検証&開発環境>
Microsoft Office 2016
<実行イメージ>
元のテキストのみ状態
セル幅、セル内の表示位置、罫線等をセット
即印刷できるように印刷範囲、ヘッダー、フッターも設定済み
<使い方>
適当なところにソースを貼り付けてください
表の体裁を自動で設定する() を実行すると処理を開始します
'********************************************
'VBAで表の体裁を自動で整える
'(1)シートを挿入しテストデータ「鮮魚の一人当たり購入数量」をセット
'(2)セル幅、罫線をセット
'(3)印刷範囲、ヘッダー、フッターをセット
'********************************************
Sub 表の体裁を自動で設定する()
Dim strwk As String
Dim lgyo As Long, lclm As Long
'新規シートを先頭に挿入
ThisWorkbook.Activate
strwk = Now
ThisWorkbook.Worksheets.Add before:=Worksheets(1)
Sheets(1).Name = "表の体裁を設定_" & Format(strwk, "yyyymmddhhmmss")
Sheets(1).Activate
'//(1)アクティブシートにテストデータをセット
SetTestData
'データの入っている最終行、最終列を取得
lgyo = Cells(Rows.Count, 1).End(xlUp).Row
lclm = Cells(5, 1).End(xlToRight).Column
'//(2)セル幅、罫線をセット
Range(Cells(1, 1), Cells(lgyo, lclm)).Select
Selection.ColumnWidth = 10
Selection.RowHeight = 20
Selection.Font.Name = "メイリオ"
Selection.Font.Size = 11
'折り返して全体を表示
Selection.WrapText = True
'水平方向、垂直方向中央揃え
Selection.HorizontalAlignment = xlCenter
Selection.VerticalAlignment = xlCenter
'A列の2行目と9行目の設定
With Range("A2", "A9")
'「折り返して全体を表示」設定なし
.WrapText = False
'「縮小して全体を表示」も念のため未設定にしておく
.ShrinkToFit = False
'水平方向左揃えを設定
.HorizontalAlignment = xlLeft
End With
'表全体に罫線を設定(実線、極細)
With Range("A4:N7")
'Bordersの引数は省略
.Borders.LineStyle = xlContinuous
.Borders.Weight = xlThin
End With
'項目行に背景色とセルの下に2本線を設定
With Range("A4:N4")
.Borders(xlEdgeBottom).LineStyle = xlDouble
.Interior.Color = RGB(169, 208, 142)
End With
'//(3)印刷範囲、ヘッダー、フッターをセット
'//PageSetupメンバーの詳細については Office DevCenter を参照
With ActiveSheet.PageSetup
'印刷時の拡大率(今回は横1ページ×縦未指定 とするため指定なし)
.Zoom = False
'横1ページ×縦未指定
.FitToPagesWide = 1
.FitToPagesTall = False
'印刷の向き(横:xlLandscape 縦:xlPortrait)
.Orientation = xlLandscape
'ヘッダーを設定
'詳細は ヘッダーとフッターに指定できる書式コード 参照
'タイトル(ゴシック・太字・24pt・下線付き)
.CenterHeader = "&""MS Pゴシック,太字""&24&U水産物の消費動向"
'日付と現在時刻
.RightHeader = "印刷日時:&D(&T)"
'フッターを設定
'ページ番号
.CenterFooter = "&P/&N"
'ブック名とシート名
.RightFooter = "&F(&A)"
'余白設定
'上3、左1.5、右1.5、下2、ヘッダー2、フッター1
.TopMargin = Application.CentimetersToPoints(3)
.LeftMargin = Application.CentimetersToPoints(1.5)
.RightMargin = Application.CentimetersToPoints(1.5)
.BottomMargin = Application.CentimetersToPoints(2)
.HeaderMargin = Application.CentimetersToPoints(2)
.FooterMargin = Application.CentimetersToPoints(1)
'水平方向ページ中央
.CenterHorizontally = True
End With
'改ページプレビュー表示
ActiveWindow.View = xlPageBreakPreview
'ズーム85%で表示
ActiveWindow.Zoom = 85
'設定終了メッセージ
Range("A1").Select
MsgBox "設定がおわりました", vbInformation
End Sub
'********************************************
'シートに「鮮魚の1人当たり購入数量ぼ品目別割合」表を作成する
'出典 水産庁「水産物の消費動向」
'********************************************
Sub SetTestData()
Dim ar As Variant, wkbuf As Variant
Dim i As Integer
ar = Array(",,,,,,,,,,,,,", _
"図2-1-4 鮮魚の1人当たり購入数量の品目別割合,,,,,,,,,,,,,", _
",,,,,,,,,,,,,単位:Kg", _
",マグロ,アジ,イワシ,カツオ,カレイ,サケ,サバ,サンマ,タイ,ブリ,イカ,タコ,その他", _
"昭和40年,0.57,1.92,0.38,0.19,0.77,0.44,1.59,0.44,0.39,0.34,1.78,0.36,5.29", _
"昭和57年,0.83,0.69,0.68,0.37,0.76,0.27,0.52,0.42,0.27,0.58,1.62,0.38,5.06", _
"平成22年,0.8,0.45,0.26,0.36,0.4,0.95,0.41,0.54,0.23,0.67,0.82,0.27,3.6", _
",,,,,,,,,,,,,", _
"資料:総務省「家計調査」(昭和40年、昭和57年は全世帯(農林漁家世帯を除く)、平成22年は二人以上の世帯(農林漁家世帯を除く))に基づき水産庁で作成,,,,,,,,,,,,,")
For i = 0 To UBound(ar)
wkbuf = Split(ar(i), ",")
'データを表示
For j = 0 To UBound(wkbuf)
Cells(i + 1, j + 1) = wkbuf(j)
Next j
Next i
End Sub
よろしければポチッと押してください
]]>
(1)WINDOWPLACEMENT構造体を使用します
・SetWindowPlacementで位置とサイズをセット
・GetWindowPlacementで位置とサイズを取得
(2)iniファイルをテスト用に自動生成します
(3)OnInitDialogでダイアログの位置とサイズを復元します
(4)OnDestroyでダイアログの位置とサイズを保持します
<動作検証&開発環境>
Visual Studio Community 2015
<使い方>
(1)windowPlacementTestプロジェクトを作成してください
・MFCアプリケーション
・ダイアログベース
(2)イベントを追加
・OnInitDialog
・OnDestroy(WM_DESTROY)
(3)メンバ関数を追加
・bExistFile(ファイルの存在チェック)
・GetIniSetting(iniファイルより情報取得)
(4)ソースをコピー
//windowPlacementTestDlg.h
class CwindowPlacementTestDlg : public CDialogEx
{
// コンストラクション
public:
CwindowPlacementTestDlg(CWnd* pParent = NULL); // 標準コンストラクター
// ダイアログ データ
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_WINDOWPLACEMENTTEST_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート
// 実装
protected:
HICON m_hIcon;
// 生成された、メッセージ割り当て関数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDestroy();
private:
CString csInifile;
BOOL bExistFile(CString csPath);
void GetIniSetting(WINDOWPLACEMENT &winplace);
};
//windowPlacementTestDlg.cpp
//定数定義
#define MAX_LEN 2048
BOOL CwindowPlacementTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// "バージョン情報..." メニューをシステム メニューに追加します。
// IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
//変数宣言
WINDOWPLACEMENT winplace;
CString csMsg;
FILE *fp;
//iniファイルのパスをcsInifile変数に保持
LPTSTR pBuff = csInifile.GetBuffer(MAX_LEN + 1);
GetModuleFileName(NULL, pBuff, MAX_LEN);
//.exeを.iniに置換
csInifile.GetBufferSetLength(wcslen(pBuff) - 3);
csInifile += L"ini";
//WINDOWPLACEMENT構造体に初期値をセット
ZeroMemory(&winplace, sizeof(WINDOWPLACEMENT));
//iniファイルの存在チェック
if (!bExistFile(csInifile)) {
//iniファイルが存在しないときファイルを生成する
WCHAR cwk[MAX_LEN];
wcscpy_s(cwk, MAX_LEN/sizeof(wchar_t), csInifile);
int err_no = _wfopen_s(&fp, cwk, L"wt");
fwrite("[WINDOWPLACEMENT]¥r¥n", wcslen(L"[WINDOWPLACEMENT]¥r¥n"),1, fp);
fwrite("length=0¥r¥n", wcslen(L"length=0¥r¥n"), 1, fp);
fwrite("flags=0¥r¥n", wcslen(L"flags=0¥r¥n"), 1, fp);
fwrite("ptMinPosition.x=0¥r¥n", wcslen(L"ptMinPosition.x=0¥r¥n"), 1, fp);
fwrite("ptMinPosition.y=0¥r¥n", wcslen(L"ptMinPosition.y=0¥r¥n"), 1, fp);
fwrite("ptMaxPosition.x=0¥r¥n", wcslen(L"ptMaxPosition.x=0¥r¥n"), 1, fp);
fwrite("ptMaxPosition.y=0¥r¥n", wcslen(L"ptMaxPosition.y=0¥r¥n"), 1, fp);
fwrite("rcNormalPosition.top=0¥r¥n", wcslen(L"rcNormalPosition.top=0¥r¥n"), 1, fp);
fwrite("rcNormalPosition.left=0¥r¥n", wcslen(L"rcNormalPosition.left=0¥r¥n"), 1, fp);
fwrite("rcNormalPosition.bottom=0¥r¥n", wcslen(L"rcNormalPosition.bottom=0¥r¥n"), 1, fp);
fwrite("rcNormalPosition.right=0¥r¥n", wcslen(L"rcNormalPosition.right=0¥r¥n"), 1, fp);
fclose(fp);
}else {
GetIniSetting(winplace);
BOOL bwk = this->SetWindowPlacement(&winplace);
}
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
/*************************************************
関数名 OnDestroy
機能 ダイアログの位置とサイズを取得して保持
*************************************************/
void CwindowPlacementTestDlg::OnDestroy()
{
CDialogEx::OnDestroy();
WINDOWPLACEMENT winplace;
WCHAR cwk[MAX_LEN];
//iniファイルの存在チェック
if (!bExistFile(csInifile)) {
//iniファイルが存在しないときは書き込みを行わない
return;
}
BOOL bwk = this->GetWindowPlacement(&winplace);
swprintf_s(cwk, L"%i", winplace.length);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"length", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.flags);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"flags", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.ptMinPosition.x);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"ptMinPosition.x", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.ptMinPosition.y);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"ptMinPosition.y", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.ptMaxPosition.x);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"ptMaxPosition.x", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.ptMaxPosition.y);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"ptMaxPosition.y", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.rcNormalPosition.top);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"rcNormalPosition.top", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.rcNormalPosition.left);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"rcNormalPosition.left", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.rcNormalPosition.bottom);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"rcNormalPosition.bottom", cwk, csInifile);
swprintf_s(cwk, L"%i", winplace.rcNormalPosition.right);
WritePrivateProfileString(L"WINDOWPLACEMENT", L"rcNormalPosition.right", cwk, csInifile);
}
/*************************************************
関数名 bExistFile
機能 ファイル・フォルダの存在をチェック
戻り値 TRUE:存在する FALSE:存在しない
*************************************************/
BOOL CwindowPlacementTestDlg::bExistFile(CString csPath)
{
//存在チェック
CFileFind fFind;
BOOL bFileExist;
bFileExist = fFind.FindFile(csPath);
fFind.Close();
return bFileExist;
}
/*************************************************
関数名 GetIniSetting
機能 ウィンドウの位置をiniファイルから読込
戻り値 WINDOWPLACEMENT構造体
*************************************************/
void CwindowPlacementTestDlg::GetIniSetting(WINDOWPLACEMENT &winplace)
{
winplace.length = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"length", 0, csInifile);
winplace.flags = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"flags", 0, csInifile);
winplace.ptMinPosition.x = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"ptMinPosition.x", 0, csInifile);
winplace.ptMinPosition.y = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"ptMinPosition.y", 0, csInifile);
winplace.ptMaxPosition.x = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"ptMaxPosition.x", 0, csInifile);
winplace.ptMaxPosition.y = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"ptMaxPosition.y", 0, csInifile);
winplace.rcNormalPosition.top = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"rcNormalPosition.top", 0, csInifile);
winplace.rcNormalPosition.left = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"rcNormalPosition.left", 0, csInifile);
winplace.rcNormalPosition.bottom = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"rcNormalPosition.bottom", 0, csInifile);
winplace.rcNormalPosition.right = GetPrivateProfileInt(L"WINDOWPLACEMENT", L"rcNormalPosition.right", 0, csInifile);
}
よろしければポチッと押してください
]]>
Range.Sortメソッドを使用して指定列で表をソートします
(1)アクティブシートにテスト用の表「日本百名山」を作成
(2)B列の「標高」で表をソートします
<動作検証&開発環境>
Microsoft Office 2016
<使い方>
適当なところにソースを張り付けてください
VBAで表をソートする() を実行するとソート処理を開始します
<実行イメージ>
ソート前とソート後のイメージです
'********************************************
'VBAでリスト(表)をソートする
'(1)アクティブシートにテスト用の表(日本百名山)を作成
'(2)標高の降順でソート(高い順でソート)
'********************************************
Sub VBAで表をソートする()
'//テストデータ「日本百名山」表を作成
SetTestData
'//標高でソートする
'//項目行を除くため2行目移行をソートする
'//Key1 : 最初の並べ替えフィールド(B列の標高で並べ替え)
'//order1: Key1で指定した値の並べ替え順序(昇順:xlAscending 降順:xlDescending)
'//Header: 最初の行にヘッダ情報が含まれているか(ヘッダを判断:xlGuess 含まれない(規定値):xlNo 含まれる:xlYes)
Columns("A:B").Sort _
Key1:=Range("B2"), _
order1:=xlDescending, _
Header:=xlYes
Range("A1").Select
End Sub
'********************************************
'アクティブシートに「日本百名山」表を作成する
'********************************************
Sub SetTestData()
Dim ar As Variant
ar = Array("百名山,標高(m)", "利尻岳,1721", "羅臼岳,1660", "斜里岳,1545", "阿寒岳,1499", "大雪山,2290", _
"トムラウシ,2141", "十勝岳,2077", "幌尻岳,2052", "後方羊蹄山,1898", "岩木山,1625", _
"八甲田山,1584", "八幡平,1613", "岩手山,2038", "早池峰山,1917", "鳥海山,2236", _
"月山,1984", "朝日岳,1870", "蔵王山,1841", "飯豊山,2128", "吾妻山,2035", _
"安達太良山,1709", "磐梯山,1819", "会津駒ヶ岳,2133", "那須岳,1917", "燧ヶ岳,2356", _
"至仏山,2228", "武尊山,2158", "男体山,2484", "奥白根山,2578", "皇海山,2144", _
"赤城山,1828", "筑波山,877", "両神山,1723", "雲取山,2017", "甲武信岳,2475", _
"金峰山,2599", "瑞牆山,2230", "大菩薩嶺,2057", "丹沢山,1673", "富士山,3776", _
"天城山,1406", "谷川岳,1977", "草津白根山,2578", "四阿山,2354", "浅間山,2568", _
"越後駒ヶ岳,2003", "平ヶ岳,2141", "巻機山,1967", "雨飾山,1963", "苗場山,2145", _
"妙高山,2454", "火打山,2462", "高妻山,2353", "白馬岳,2932", "五竜岳,2814", _
"鹿島槍ヶ岳,2889", "剱岳,2998", "立山,3015", "薬師岳,2926", "黒部五郎岳,2840", _
"水晶岳,2986", "鷲羽岳,2924", "槍ヶ岳,3180", "穂高岳,3190", "常念岳,2857", _
"笠ヶ岳,2897", "焼岳,2455", "乗鞍岳,3026", "御嶽山,3067", "美ヶ原,2034", _
"霧ヶ峰,1925", "蓼科山,2530", "八ヶ岳,2899", "木曽駒ヶ岳,2956", "空木岳,2864", _
"恵那山,2191", "甲斐駒ヶ岳,2967", "仙丈ヶ岳,3033", "鳳凰山,2840", "北岳,3192", _
"間ノ岳,3189", "塩見岳,3052", "悪沢岳,3141", "赤石岳,3120", "聖岳,3013", _
"光岳,2591", "白山,2702", "荒島岳,1523", "伊吹山,1377", "大台ヶ原山,1695", _
"大峰山,1915", "大山,1729", "剣山,1955", "石鎚山,1982", "九重山,1791", _
"祖母山,1756", "阿蘇山,1592", "霧島山,1700", "開聞岳,924", "宮之浦岳,1936")
ThisWorkbook.Activate
Cells.Select
Selection.Clear
Selection.ColumnWidth = 15
Selection.RowHeight = 30
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 10
'//折り返して全体を表示する
Selection.WrapText = True
Range("A1").Select
'//データをシートに展開
Dim i As Integer, j As Integer
Dim wkbuf As Variant
For i = 0 To UBound(ar)
wkbuf = Split(ar(i), ",")
'不正なデータであれば次レコードへ
If UBound(wkbuf) <> 1 Then GoTo nextrec
'データを表示
For j = 0 To UBound(wkbuf)
Cells(i + 1, j + 1) = wkbuf(j)
Next j
nextrec:
Next i
'//罫線を引く
With Range("A1:B" & CStr(UBound(ar) + 1)).Borders
.LineStyle = xlContinuous
.Weight = xlMedium
End With
'//項目行の背景色をセット
With Range("A1:B1")
.Interior.Color = RGB(0, 255, 130)
.HorizontalAlignment = xlHAlignCenter
.VerticalAlignment = xlVAlignCenter
End With
End Sub
よろしければポチッと押してください
]]>(1)アクティブシートにテスト用の表を自動作成します
過去5年間のパリーグ勝利数
出典:日本野球機構 年度別成績
(2)埋め込みグラフを作成します(表と同じシートに作成)
(3)グラフのパーツを設定します
<動作検証&開発環境>
Microsoft Office 2016
<使い方>
適当なところにソースを張り付けてください
VBAでグラフを作成する()を呼び出すと埋め込みグラフ作成処理を開始します
<実行イメージ>
テスト表を作成し、左50、トップ250位置よりグラフを出力します
'********************************************
'VBAでグラフを自動作成する
'(1)アクティブシートにテスト用の表を作成
'(2)埋め込みグラフを作成(表と同じシートにグラフを作成)
'(3)グラフのパーツを設定する
'********************************************
Sub VBAでグラフを作成する()
Dim gyo As Long
Dim clm As Long
'//(1)テストデータ「過去5年間のパリーグ勝利数」表を作成
SetTestData
'//データの入っている最終行、最終列を取得
gyo = Cells(Rows.Count, 1).End(xlUp).Row
clm = Cells(1, Columns.Count).End(xlToLeft).Column
'//(2)埋め込みグラフを作成
'// 左:50 トップ:250 幅:500 高さ:350
Set co = ActiveSheet.ChartObjects.Add(50, 250, 500, 350)
'// グラフの種類は「積み上げ縦棒」
'// グラフの種類についてはOffice Dev Centerを参照
co.Chart.ChartType = xlColumnStacked
'// グラフのデータソースを指定
co.Chart.SetSourceData Source:=Range(Cells(1, 1), Cells(gyo, clm))
'//(3)グラフパーツの設定
'// グラフのタイトルを表示
co.Chart.HasTitle = True
'// グラフのタイトルを設定
co.Chart.ChartTitle.Font.Name = "メイリオ"
co.Chart.ChartTitle.Text = "過去5年間のパリーグ勝利数"
'// 軸ラベルの書式設定
'// AxesのxlCategoryはX軸、xlValueはY軸
co.Chart.Axes(xlCategory).TickLabels.Font.Name = "メイリオ"
co.Chart.Axes(xlCategory).TickLabels.Font.Size = 9
co.Chart.Axes(xlValue).TickLabels.Font.Name = "メイリオ"
co.Chart.Axes(xlValue).TickLabels.Font.Size = 9
'// 軸の表示方向を指定する
'// 反時計回りの角度を指定(マイナスを指定すると時計回り)
co.Chart.Axes(xlCategory).TickLabels.Orientation = 45
co.Chart.Axes(xlValue).TickLabels.Orientation = 0
'// 凡例を表示
co.Chart.HasLegend = True
'// 凡例の位置を指定(下に表示)
co.Chart.Legend.Position = xlLegendPositionTop
'xlLegendPositionBottom 下
'xlLegendPositionCorner 右上
'xlLegendPositionLeft 左
'xlLegendPositionRight 右
'xlLegendPositionTop 上
'// 背景色に緑(204, 255, 204)をセット
co.Chart.ChartArea.Interior.Color = RGB(204, 255, 204)
'// 枠線(二点鎖線)をセット
co.Chart.ChartArea.Border.LineStyle = xlDashDotDot
'xlContinuous 実線 (細)
'xlDash 破線
'xlDashDot 一点鎖線
'xlDashDotDot 二点鎖線
'xlDot 点線
'xlDouble 二重線
'xlSlantDashDot 斜め斜線
'xlLineStyleNone 無し
End Sub
'********************************************
'アクティブシートに「過去5年間のパリーグ勝利数」表を作成する
'出典 日本野球機構 年度別成績
'********************************************
Sub SetTestData()
Dim ar As Variant
ar = Array( _
"チーム名,2011年,2012年,2013年,2014年,2015年", _
"福岡ソフトバンクホークス,88,67,73,78,90", _
"北海道日本ハムファイターズ,72,74,64,73,79", _
"千葉ロッテマリーンズ,54,62,74,66,73", _
"埼玉西武ライオンズ,68,72,74,63,69", _
"オリックス・バファローズ,69,57,66,80,61", _
"東北楽天ゴールデンイーグルス,66,67,82,64,57")
ThisWorkbook.Activate
Cells.Select
Selection.Clear
Selection.ColumnWidth = 15
Selection.RowHeight = 30
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 10
'//折り返して全体を表示する
Selection.WrapText = True
Range("A1").Select
'//全てのグラフを削除
Dim objShape As Shape
For Each objShape In ActiveSheet.Shapes
objShape.Delete
Next
'//データをシートに展開
Dim i As Integer, j As Integer
Dim wkbuf As Variant
For i = 0 To UBound(ar)
wkbuf = Split(ar(i), ",")
'不正なデータであれば次レコードへ
If UBound(wkbuf) <> 5 Then GoTo nextrec
'データを表示
For j = 0 To UBound(wkbuf)
Cells(i + 1, j + 1) = wkbuf(j)
Next j
nextrec:
Next i
End Sub
よろしければポチッと押してください
]]>
(1)strtok_s を使用してカンマ区切り文字列を分割します
(2)AfxExtractSubStringを使用してカンマ区切り文字列を分割します
(3)カンマ区切り文字列を分割した結果をコマンドプロンプトに出力します
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
上がCSVをstrtok_s を使用して分割した結果
下がCSVをAfxExtractSubStringを使用して分割した結果
<使い方>
(1)Win32コンソールアプリケーションでプロジェクトを作成
(2)[次へ]を押下し、アプリケーション設定画面の共通ヘッダーファイルを追加にて「MFC」にチェック
(3)構成プロパティ > 全般 > 文字セット で「マルチバイト文字セットを使用する」を指定
(4)ソースの追加
//テスト用CSVデータを定義
//りんごの収穫量ランキングベスト10(2014年)
//農水省統計データより引用
//http://www.machimura.maff.go.jp/machi/search/index.php
char *cApple[] = {
"1,青森県 ,468000",
"2,長野県 ,162900",
"3,山形県 ,52400",
"4,岩手県 ,46500",
"5,福島県 ,27600",
"6,秋田県 ,22100",
"7,群馬県 ,9050",
"8,北海道 ,8450",
"9,宮城県 ,3840",
"10,栃木県 ,3060",
"0,"
};
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: MFC の初期化ができませんでした。¥n");
nRetCode = 1;
}
else
{
/* 【 C++言語編 】 */
/* (1)strtok_sを使って文字列を分割 */
/* Developer Networkはこちら */
/* https://msdn.microsoft.com/ja-jp/library/ftsafwz3.aspx */
printf("(1)strtok_sを使って文字列を分割¥n");
char apple[1024];
char buf[1024];
char cwk[1024];
//デリミタ(区切り文字)にカンマを指定
char deli[] = ",";
//char deli[] = "¥t"; //タブを指定する場合
//char deli[] = " ,¥t" //半角スペースとカンマとタブを指定する場合
//トークン
char *token = NULL;
char *next = NULL;
for (int i=0;;i++){
ZeroMemory(&buf, sizeof(buf));
//最初のカンマ区切り文字取得
ZeroMemory(&apple, sizeof(apple));
strcpy_s(apple, sizeof(apple), cApple[i]);
token = strtok_s(apple, deli, &next);
//ループ終了条件(0が出現したら終了)
if (strcmp(token, "0") == 0) break;
//取得したトークンを保持
strcpy_s(buf, sizeof(buf), token);
//次のトークンを取得
while (1) {
ZeroMemory(&cwk, sizeof(cwk));
token = strtok_s(NULL, deli, &next);
//トークンがNULLなら取得終了
if (token == NULL) break;
sprintf_s(cwk, " %s", token);
strcat_s(buf, sizeof(cwk) - strlen(cwk) - 1, cwk);
}
//コンソール出力
printf("%02dレコード目--> %s ", (i + 1), buf);
system("pause");
}
/* 【 MFC編 】 */
/* (2)AfxExtractSubStringを使って文字列を分割 */
/* Developer Networkはこちら */
/* https://msdn.microsoft.com/ja-jp/library/aa991543.aspx */
printf("¥n(2)AfxExtractSubStringを使って文字列を分割¥n");
CString csapple;
CString csbuf;
CString cswk;
for (int i = 0;; i++) {
csbuf = "";
//最初のカンマ区切り文字取得
//最終データを取得するため最後尾にカンマを付加する
csapple.Format("%s,,,", cApple[i]);
if (csapple.Left(1) == "0") break;
//カンマ区切りデータを取得
for (int j = 0; j < 3;j++) {
cswk = "";
AfxExtractSubString(cswk, csapple, j, ',');
csbuf += (cswk + " ");
}
//最後尾にスペースを付加
csbuf += " ";
//コンソール出力
printf("%02dレコード目--> %s", (i + 1), (LPCSTR)csbuf);
system("pause");
}
}
}
else
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: GetModuleHandle が失敗しました¥n");
nRetCode = 1;
}
return nRetCode;
}
よろしければポチッと押してください
]]>
(1)新規ブックを作成し保存します
シート数を指定して新規ブックを作成します
シート名を変更します
(2)ブックを開きます
(3)ブックを編集後、保存します
上書き保存
名前を付けて保存(サンプル掲載)
名前を付けてパスワード付きで保存(サンプル掲載)
Webページとして保存(サンプル掲載)
ダイアログボックス(Dialogs)で保存(サンプル掲載)
<使い方>
適当なところにソースを張り付けてください
ブックの新規作成と保存()を呼び出すとブックの操作を行います
新規ブック作成
→新規ブックを保存
→ブックを開く
→ブックを編集
→上書き保存(他サンプルあり)
<イメージ>
ブックを新規作成する際のシート数は オプション > 基本設定 > ブックのシート数(S) に設定されていますが一時的に変更します
サンプルデータを設定してブックを保存します
よろしければポチッと押してください
]]>
(1)2種類のファイル選択ダイアログを表示します
・単一ファイルを選択
・複数ファイルを選択
(2)初期フォルダを設定します
(3)2回目以降は前回選択したフォルダを初期表示します
(4)ファイルフィルターを3つ(.bmp/.dat/.*)から選択できます
(5)単一ファイル選択時は選択ファイルパスを表示します
(6)複数ファイル選択時は選択フォルダパスと選択ファイル一覧を表示します
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
[ファイル選択1]ボタンで単一ファイルを選択できます
[ファイル選択2]ボタンで複数ファイルを同時選択できます
<使い方>
(1)ダイアログベースでプロジェクト(FileSelect)を作成
(2)ダイアログにコントロールを配置
(3)エディットボックス、リストボックスにメンバ変数を追加
・IDC_EDIT1
変数名:m_Edt1
アクセス:private
変数の種類:CString
コントロール変数:チェックOn
カテゴリ:Value
・IDC_EDIT2
変数名:m_Edt2
アクセス:private
変数の種類:CString
コントロール変数:チェックOn
カテゴリ:Value
・IDC_LIST1
変数名:m_List1
アクセス:private
変数の種類:CListBox
コントロール変数:チェックOn
カテゴリ:Control
(4)ボタンクリックイベントを追加
(5)コードを記述
//FileSelectDlg.h
//メンバ変数を追加(自動で追加されるものを含む)
//FileSelectDlg.cpp
/*************************************************
関数名 SplitFilePath
機能 最後の'¥'から分割した文字列を返す
csPath : 対象のファイルパス
kbn : 1('¥'より前) 1以外('¥'より後)
*************************************************/
CString SplitFilePath(CString csPath, int kbn)
{
return kbn == 1 ? csPath.Left(csPath.ReverseFind('¥¥')) : csPath.Mid(csPath.ReverseFind('¥¥') + 1);
}
よろしければポチッと押してください
]]>(1)下記手順にてメモリデバイスコンテキストにビットマップを割付
・GetDC
・CreateCompatibleDC
・CreateCompatibleBitmap
・SelectObject
(2)メモリデバイスコンテキスト(DC)に文字を出力します
・メイリオのサイズ26でフォントオブジェクトを生成
・文字列をTextOutWにてDCに出力
・横方向中央揃えで出力(GetTextExtentPoint32W)
(3)メモリデバイスコンテキスト(DC)に図形を出力します
・ペンオブジェクトを生成(CreatePen)
・Ellipseで楕円を出力
・Polygonで三角形を出力
(4)下記手順にて2色ビットマップファイルを出力
・イメージデータサイズを取得(幅を4バイト揃え)
・BITMAPFILEHEADERをセット
・BITMAPINFOHEADERをセット
・GetDIBitsにてイメージデータ部をセット
<動作検証&開発環境>
Visual Studio Community 2015
<イメージ>
白:RGB(0xFF,0xFF,0xFF)とピンク:RGB(0xCC,0x00,0x99)の2色ビットマップを作成
サイズは400×300
<使い方>
(1)Win32コンソールアプリケーションでプロジェクトを作成
(2)アプリケーション設定で「MFC」にチェック
(3)プロトタイプ宣言(1~5行)
(4)構造体定義(7~18行)
(5)main()以下を修正&追加
//プロトタイプ宣言
void DrawStringToHDC(HDC hdc, CStringW csw, int iXsize, int iYpos);
HFONT SetFontStyle(const CStringW cfname, int ifsize);
void SetBmpFileHeader(BITMAPFILEHEADER *bmFileh, int imgSize);
void SetBmpInfoHeader(BITMAPINFOHEADER *bmInfoh, int imgSize, int iXsize, int iYsize);
//RGBQUAD構造体配列(本サンプルでは色ビット数=1で作成のため2色)
int Palette[2] = {
0x00CC0099, //本サンプルではRGB(CC,00,99)を指定
0x00FFFFFF,
};
//ビットマップ情報構造体とカラーパレット
//GetDIBitsで使用するBITMAPINFO構造体
struct SCT_BMPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiPalette[2];
};
// 唯一のアプリケーション オブジェクトです。
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
//〜〜省略〜〜
}
else
{
BITMAPFILEHEADER bmFileh;
BITMAPINFOHEADER bmInfoh;
SCT_BMPINFO bmInfo;
FILE *fp;
int iXsize = 400; //画像の幅(Width)
int iYsize = 300; //画像の高さ(Height)
/* 描画対象のデバイスコンテキストを用意 */
//スクリーンのデバイスコンテキストを用意
HDC hdcScreen = GetDC(0);
HDC hdc = CreateCompatibleDC(hdcScreen);
//スクリーンのビットマップを用意(400×300ピクセル)
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, iXsize, iYsize);
//スクリーンのデバイスコンテキストにビットマップを割付
HBITMAP hBmpOld = (HBITMAP)SelectObject(hdc, hBmp);
/* デバイスコンテキストに描画を行う */
//フォントオブジェクトを生成
HFONT hFont,hFontOld;
int iFsize = 26;
hFont = SetFontStyle(L"メイリオ", iFsize);
hFontOld = (HFONT)SelectObject(hdc, hFont);
//背景を白で塗りつぶし
RECT rect;
SetRect(&rect, 0, 0, iXsize, iYsize);
FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
//文字を出力する
DrawStringToHDC(hdc, L"メモリデバイスコンテキストに文字を出力します", iXsize,40);
DrawStringToHDC(hdc, L"全角:あいうえお 半角:12345ABCDEカキクケコ", iXsize, 70);
DrawStringToHDC(hdc, L"袋熊(コアラ)海豹(アザラシ)珊瑚(サンゴ)", iXsize, 100);
//図形を出力する
POINT pt[3];
HPEN hPen, hPenOld;
hPen = CreatePen(PS_SOLID, 8, RGB(0xCC, 0, 0x99));
hPenOld = (HPEN)SelectObject(hdc, hPen);
Ellipse(hdc, 50, 150, 180, 270);
pt[0].x = 285;
pt[0].y = 150;
pt[1].x = 220;
pt[1].y = 270;
pt[2].x = 350;
pt[2].y = 270;
Polygon(hdc,pt, 3);
/* ビットマップファイル(色ビット数=1bit)に保存 */
//イメージデータ部のサイズを取得(1画素あたり1bit)
//行単位で4バイト(32ビット)単位に揃えなければならない
int imgSize;
if ((iXsize % 32) == 0) {
//画像の幅が4バイト単位になっているとき
imgSize = iXsize * iYsize;
}
else {
//画像の幅を4バイト単位に揃える
imgSize = ((32 / 8) * ((int)(iXsize / 32) + 1)) * iYsize;
}
//イメージデータ部の格納バッファ
void *lpImgbuf;
lpImgbuf = (void *)malloc(imgSize);
//ビットマップファイルヘッダ(14バイト)に値をセット
SetBmpFileHeader(&bmFileh, imgSize);
//ビットマップ情報ヘッダ(40バイト)に値をセット
SetBmpInfoHeader(&bmInfoh, imgSize, iXsize, iYsize);
//GetDIBitsにてイメージデータを生成
//DIBの原点はビットマップの左下隅
//データはリトルエンディアンにて記録される
bmInfo.bmiHeader = bmInfoh;
memcpy(bmInfo.bmiPalette, Palette, sizeof(Palette));
GetDIBits(hdc, hBmp, 0, iYsize,lpImgbuf, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
//出力ファイル名の生成(result+年月日時分秒)
CTime ct = CTime::GetCurrentTime();
char cFile[2048];
ZeroMemory(&cFile, sizeof(cFile));
sprintf_s(cFile,".¥¥result_%04d%02d%02d%02d%02d%02d.bmp", ct.GetYear(), ct.GetMonth(), ct.GetDay(), ct.GetHour(), ct.GetMinute(), ct.GetSecond());
//ファイルへ出力
int ierr = fopen_s(&fp, (char*)cFile, "wb");
fwrite(&bmFileh, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&bmInfoh, sizeof(BITMAPINFOHEADER), 1, fp);
fwrite(Palette, sizeof(Palette), 1, fp);
fwrite(lpImgbuf, imgSize, 1, fp);
fclose(fp);
//終了処理
DeleteObject(hBmp);
DeleteObject(hFont);
DeleteObject(hPen);
DeleteDC(hdc);
ReleaseDC(0, hdcScreen);
//バッファを解放
free(lpImgbuf);
//終了メッセージ
MessageBox(NULL, L"ビットマップの出力処理が終了しました", L"処理終了", MB_ICONINFORMATION);
}
}
else
{
//〜〜省略〜〜
}
return nRetCode;
}
/*************************************************
関数名 DrawStringToHDC
機能 メモリデバイスコンテキストに文字列を出力
iXsize : 出力画像の幅(Width)
iYpos : 縦方向の出力位置
*************************************************/
void DrawStringToHDC(HDC hdc, CStringW csw, int iXsize,int iYpos)
{
wchar_t wct[512];
SIZE sz;
ZeroMemory(&wct, 512);
wcscpy_s(wct, csw);
//中央に描画する
GetTextExtentPoint32W(hdc, wct, lstrlenW(wct), &sz);
TextOutW(hdc, (iXsize - sz.cx) / 2, iYpos, wct, lstrlenW(wct));
}
/*************************************************
関数名 SetBmpFileHeader
機能 BITMAPFILEHEADER構造体をセット
bmFileh : BITMAPFILEHEADER構造体
imgSize : データ部のサイズ
*************************************************/
void SetBmpFileHeader(BITMAPFILEHEADER *bmFileh, int imgSize)
{
int ofs;
//イメージデータまでのサイズ
//本サンプルでは2色ビットマップ(色ビット数=1)のためカラーパレットは2個
//(参考)色ビット数=4(1画素あたり4ビット)のときパレットは16個
//(参考)色ビット数=8(1画像あたり8ビット)のときパレットは256個
//(参考)色ビット数=24(1画素あたり3バイト)のときパレットなし
//(参考)色ビット数=32(1画素あたり4バイト)のときパレットなし
ofs = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ sizeof(Palette);
ZeroMemory(bmFileh, sizeof(BITMAPFILEHEADER));
bmFileh->bfType = 0x4D42; //BM
bmFileh->bfSize = ofs + imgSize;
bmFileh->bfOffBits = ofs;
return;
}
/*************************************************
関数名 SetBmpInfoHeader
機能 BITMAPINFOHEADER構造体をセット
bmFileh : BITMAPINFOHEADER構造体
imgSize : データ部のサイズ
iXsize : ビットマップの幅(Width)
iYsize : ビットマップの高さ(Height)
*************************************************/
void SetBmpInfoHeader(BITMAPINFOHEADER *bmInfoh, int imgSize,int iXsize,int iYsize)
{
ZeroMemory(bmInfoh, sizeof(BITMAPINFOHEADER));
bmInfoh->biSize = 40;
bmInfoh->biWidth = iXsize;
bmInfoh->biHeight = iYsize;
bmInfoh->biPlanes = 1;
//色ビット数(biBitCount)について
//1 : 本サンプルでは2色ビットマップのため1をセット
//(参考)4 : 色ビット数=4(1画素あたり4ビット)のとき16色
//(参考)8 : 色ビット数=8(1画像あたり8ビット)のとき256色
//(参考)24: 色ビット数=24(1画素あたり3バイト)のとき1677万色
//(参考)32: 色ビット数=32(1画素あたり4バイト)のとき1677万色
bmInfoh->biBitCount = 1;
bmInfoh->biSizeImage = imgSize;
return;
}
/*************************************************
関数名 SetFontStyle
機能 フォントオブジェクトを生成
https://msdn.microsoft.com/ja-jp/library/2ek64h34.aspx
*************************************************/
HFONT SetFontStyle(const CStringW cfname, int ifsize)
{
LOGFONT lf;
memset(&lf, 0x0, sizeof(LOGFONT));
//フォントの高さを指定
lf.lfHeight = ifsize;
//フォントの文字セット
lf.lfCharSet = DEFAULT_CHARSET;
//希望する出力精度を指定
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
//希望するクリッピング精度を指定
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
//フォントの出力品質を指定
lf.lfQuality = DEFAULT_QUALITY;
//フォントのピッチとファミリを指定
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
//フォントのタイプフェイス名を指定
lstrcpy(lf.lfFaceName, (LPCWSTR)cfname);
//LOGFONT 構造体で指定された特性でCFontオブジェクトを初期化する
return CreateFontIndirect(&lf);
}
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>//CTLCOLOR.h
//Publicメンバ変数を追加(ブラシ、COLORREF、フォント)
class CCTLCOLORApp : public CWinApp
{
public:
CCTLCOLORApp();
// オーバーライド
public:
virtual BOOL InitInstance();
CBrush m_Cbr;
COLORREF m_Clr;
CFont m_Font10, m_Font14;
//〜〜省略〜〜
};
//CTLCOLOR.cpp
//ブラシとフォントを作成
BOOL CCTLCOLORApp::InitInstance()
{
//〜〜省略〜〜
//うすい緑色をCOLORREF型にセット
m_Clr = RGB(153, 255, 102);
//ブラシを作成
m_Cbr.CreateSolidBrush(m_Clr);
//MSゴシックで小さいフォントを作成
m_Font10.CreateFont(12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DRAFT_QUALITY, DEFAULT_PITCH, _T("MS ゴシック"));
//MS明朝で大きいフォントを作成
m_Font14.CreateFont(18, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DRAFT_QUALITY, DEFAULT_PITCH, _T("MS 明朝"));
CCTLCOLORDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
//〜〜省略〜〜
// ダイアログは閉じられました。アプリケーションのメッセージ ポンプを開始しないで
// アプリケーションを終了するために FALSE を返してください。
return FALSE;
}
/*************************************************
関数名 ExitInstance
機能 インスタンスを終了する
*************************************************/
int CCTLCOLORApp::ExitInstance()
{
BOOL brtn;
//ブラシオブジェクトの破棄
brtn = m_Cbr.DeleteObject();
if (!brtn) AfxMessageBox(_T("失敗しました:m_Cbr.DeleteObject()"), MB_ICONERROR);
//フォントオブジェクトの破棄
brtn = m_Font10.DeleteObject();
if (!brtn) AfxMessageBox(_T("失敗しました:m_Font10.DeleteObject()"), MB_ICONERROR);
brtn = m_Font14.DeleteObject();
if (!brtn) AfxMessageBox(_T("失敗しました:m_Font14.DeleteObject()"), MB_ICONERROR);
return CWinApp::ExitInstance();
}
//CTLCOLORDlg.h
//App : CCTLCOLORクラスのブラシ、フォントを使用するためのインスタンス
//m_xCheck1 : CHECK型のコントロール変数
class CCTLCOLORDlg : public CDialogEx
{
//〜〜省略〜〜
private:
CCTLCOLORApp* App;
CButton m_xCheck1;
};
//CTLCOLORDlg.cpp
//OnInitDialog()にてフォントをセット
//OnCtlColor()にて背景色をセット
BOOL CCTLCOLORDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
//〜〜省略〜〜
//ダイアログのタイトルバーをセット
this->SetWindowText(_T("ダイアログの背景色、フォントの初期設定サンプル"));
/***** フォント設定ここから *****/
//m_Font10 : MSゴシックで小さいフォント
//m_Font14 : MS明朝で大きいフォント
//ラベルのフォントをセット
this->GetDlgItem(IDC_STATIC1)->SetFont(&App->m_Font10);
this->GetDlgItem(IDC_STATIC2)->SetFont(&App->m_Font14);
//エディットボックスのフォントをセット
this->GetDlgItem(IDC_EDIT1)->SetFont(&App->m_Font10);
this->GetDlgItem(IDC_EDIT1)->SetWindowText(_T("フォントテストサンプルテキスト(IDC_EDIT1)"));
//チェックボックスのフォントをセット
this->GetDlgItem(IDC_CHECK1)->SetFont(&App->m_Font10);
this->GetDlgItem(IDC_CHECK2)->SetFont(&App->m_Font14);
this->GetDlgItem(IDC_CHECK3)->SetFont(&App->m_Font10);
//ラジオボタンのフォントをセット
this->GetDlgItem(IDC_RADIO1)->SetFont(&App->m_Font10);
this->GetDlgItem(IDC_RADIO2)->SetFont(&App->m_Font14);
/***** フォント設定ここまで *****/
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
/*************************************************
関数名 OnCtlColor
機能 ユーザ描画するときにフレームワークが呼び出します
*************************************************/
HBRUSH CCTLCOLORDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
switch (nCtlColor) {
//ダイアログの背景色を設定
case CTLCOLOR_DLG:
if (*pWnd == *this) {
//背景色セット
return App->m_Cbr;
}
break;
//スタティックコントロールの背景色を設定
case CTLCOLOR_STATIC:
//ラベル(IDC_STATIC1)の背景色を設定
if (*pWnd == *this->GetDlgItem(IDC_STATIC1)) {
pDC->SetBkColor(App->m_Clr);
return App->m_Cbr;
}
//ラジオボタンの背景色を設定
if ((*pWnd == *this->GetDlgItem(IDC_RADIO1)) || (*pWnd == *this->GetDlgItem(IDC_RADIO2))) {
pDC->SetBkColor(App->m_Clr);
return App->m_Cbr;
}
//コントロール型のメンバ変数(m_xCheck1)でコントロールを指定することもできます
//チェックボックスの上段の背景色を設定
if ((*pWnd == m_xCheck1) || (*pWnd == *this->GetDlgItem(IDC_CHECK2))) {
return App->m_Cbr;
}
break;
//エディットボックスの背景色とテキスト色を設定
case CTLCOLOR_EDIT:
if (*pWnd == *this->GetDlgItem(IDC_EDIT1)) {
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkColor(App->m_Clr);
return App->m_Cbr;
}
break;
//ボタンを指定するとボタンの淵がきれいになります
case CTLCOLOR_BTN:
pDC->SetBkColor(App->m_Clr);
return App->m_Cbr;
default:
break;
}
return hbr;
}
よろしければポチッと押してください
]]>
<動作検証&開発環境>
Microsoft Office 2016
<使い方>
適当なところにソースを張り付けてください
オートフィルタを設定する()を呼び出すと2秒毎に上記抽出を実施します
<実行イメージ>
テスト用の表を自動作成
AutoFilterメソッドで抽出
よろしければポチッと押してください
]]>
セクション名 | キー名 | 設定値 | 取得API | 取得値 |
---|---|---|---|---|
MOJI_SECTION | moji1 | あいうえおかきくけこ | GetPrivateProfileString | あいうえおかきくけこ |
moji2 | "さしすせそたちつてと" | GetPrivateProfileString | さしすせそたちつてと | |
moji3 | GetPrivateProfileString | |||
NUMBER_SECTION | num1 | 123456 | GetPrivateProfileInt | 123456 |
num2 | abc | GetPrivateProfileInt | 0(数値に変換できないため) | |
num3 | GetPrivateProfileInt | 0(設定なしのためGetPrivateProfileIntの第3引数で指定した初期値) |
<動作検証&開発環境>
Microsoft Office 2010
<使い方>
ソース全体をそのまま張り付けてください
初期設定情報を取得()を呼び出すと処理を開始します
サンプルini作成 → 設定値取得 → メッセージに結果出力
よろしければポチッと押してください
]]>//定数定義とプロトタイプ宣言をヘッダファイルあるいはソースの先頭に追加してください
//定数定義
const int MAX_LEN = 2048;
//プロトタイプ宣言
BOOL SelectFolder(HWND hWnd, LPCTSTR lpDefFolder, LPTSTR lpSelectPath, UINT iFlg, CString ttl);
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
void FindAllFile(CString dir, CStringArray &csalist);
// 唯一のアプリケーション オブジェクトです。
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
//〜〜中略〜〜
}
else
{
char cDirSel[MAX_LEN] = {'¥0'};
CString csMsg;
CStringArray csalist;
int i;
FILE *fp;
//フォルダ選択で初期表示パスを指定
CString csDefaultFol = "C:¥¥";
//フォルダ選択ダイアログを表示する
//フォルダ選択ダイアログについては「http://pg-sample.sagami-ss.net/?eid=3」参照
if( SelectFolder(NULL, csDefaultFol, cDirSel, BIF_RETURNONLYFSDIRS, "XXXフォルダーを選択してください") )
{
//バッファをクリア
csalist.RemoveAll();
//再帰的にサブフォルダまで検索しファイル一覧を取得
FindAllFile(cDirSel, csalist);
}
else
{
//キャンセルされた
return 0;
}
//取得したファイル一覧を出力するファイルをオープン
int ierr = fopen_s(&fp, ".¥¥filelist.txt", "wb");
if (ierr != 0) {
AfxMessageBox("結果出力ファイルのオープン(書き込みモード)に失敗しました。処理を中止します。",MB_ICONSTOP);
return 0;
}
//ファイル一覧を出力する
csMsg.Format("ルートフォルダ [ %s ]¥r¥n", cDirSel);
fputs(csMsg, fp);
for (i = 0; i < csalist.GetSize(); i++)
{
fputs(csalist.GetAt(i) + "¥r¥n",fp);
}
csMsg.Format("検索ファイル数 [ %d ]¥r¥n",csalist.GetSize());
fputs(csMsg, fp);
int numclosed = _fcloseall();
AfxMessageBox("終了しました", MB_ICONINFORMATION);
}
}
else
{
//〜〜中略〜〜
}
return nRetCode;
}
/****************************************************************
指定フォルダを検索してファイル一覧作成(サブフォルダも検索する)
引数 検索するルートフォルダ
戻り値 ファイルリスト
****************************************************************/
void FindAllFile(CString dir, CStringArray &csalist)
{
CFileFind cFileFind;
CString strSearchFile = dir + ("¥¥*");
BOOL rtn;
CString cwk, cext;
//対象ファイルを検索
if (!cFileFind.FindFile(strSearchFile))
{
return;
}
else {
do
{
rtn = cFileFind.FindNextFile();
//".",".."でない場合に処理を行う
if (!cFileFind.IsDots()) {
cwk = cFileFind.GetFilePath();
//フォルダなら再帰的に検索を実行する
if (cFileFind.IsDirectory()) {
TRACE("検索中です... [ %s ]¥r¥n", dir);
//サブフォルダを検索する
FindAllFile(cwk, csalist);
}
else {
//拡張子を指定して検索する場合の実装例です
//例:txtファイルを抽出対象とする
//cext = cwk.Right(4);
//if ((cext.MakeUpper()) == ".TXT") {
// csalist.Add(cwk);
//}
//本サンプルでは全てのファイルを抽出対象とします
csalist.Add(cwk);
}
}
} while (rtn);
cFileFind.Close();
}
return;
}
/************************************************************
フォルダを指定(SelectFolder)
引数(IN):
hWnd ウインドウハンドル
lpDefFolder デフォルトで表示するフォルダパス
iFlg ダイアログオプション
ttl ダイアログのタイトルテキスト
引数(OUT):
lpSelectPath 選択されたフォルダパス
************************************************************/
BOOL SelectFolder(HWND hWnd, LPCTSTR lpDefFolder, LPTSTR lpSelectPath, UINT iFlg, CString ttl)
{
LPMALLOC pMalloc;
BOOL brtn = FALSE;
//IMallocインターフェイスへのポインタを取得
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
BROWSEINFO brows;
ITEMIDLIST *pIDlist;
//BROWSEINFO構造体の初期化
memset(&brows, NULL, sizeof(brows));
//BROWSEINFO構造体に値をセット
brows.hwndOwner = hWnd;
brows.pszDisplayName = lpSelectPath;
brows.lpszTitle = ttl;
brows.lParam = (LPARAM)lpDefFolder;
brows.pidlRoot = NULL;
brows.ulFlags = iFlg;
brows.lpfn = &BrowseCallbackProc;
brows.iImage = (int)NULL;
//フォルダ選択ダイアログの表示
pIDlist = SHBrowseForFolder(&brows);
if (pIDlist == NULL)
//何も選択されなければデフォルトフォルダを返す
strcpy_s(lpSelectPath, MAX_LEN, lpDefFolder);
else {
//ITEMIDLIST からフルパスを得る
SHGetPathFromIDList(pIDlist, lpSelectPath);
brtn = TRUE;
//ITEMIDLIST の開放
pMalloc->Free(pIDlist);
}
pMalloc->Release();
}
return brtn;
}
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
switch (uMsg)
{
case BFFM_INITIALIZED:
//初期化処理(初期表示フォルダ指定)
SendMessage(hWnd, BFFM_SETSELECTION, (WPARAM)TRUE, lpData);
break;
case BFFM_SELCHANGED:
//フォルダ選択ダイアログでフォルダが選択された時に処理が必要であればここに記載
TRACE("フォルダが選択されました?r?n");
break;
}
return 0;
}
よろしければポチッと押してください
]]>
//インクルード
#include <stdio.h>
// 唯一のアプリケーション オブジェクトです
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
//〜〜中略〜〜
}
else
{
const int MAX_LEN = 2048;
FILE *fp;
errno_t err_no;
int iret,i;
CString csPath = "tmp.txt";
CString csErr;
int numclosed;
//fopen_sによるファイル入出力
//https://msdn.microsoft.com/ja-jp/library/z5hh6ee9.aspx
//読込モード:r ファイルが存在しない時はエラー
//書込モード:w ファイルが既にオープンされているときはエラー
//追記モード:a ファイルが存在しない時は新規作成、すでにオープンされているときはエラー
//書き込みデータを定義
//書き込みをバイナリモード(wb)で行う場合は改行をcrlf(¥r¥n)とします
const char irohauta[8][MAX_LEN] = {
{ "いろはにほへと ちりぬるを¥n" },
{ "わかよたれそ つねならむ¥n" },
{ "うゐのおくやま けふこえて¥n" },
{ "あさきゆめみし ゑひもせす¥n" },
{ "色はにほへど 散りぬるを¥n" },
{ "我が世たれぞ 常ならむ¥n" },
{ "有為の奥山 今日越えて¥n" },
{ "浅き夢見じ 酔ひもせず¥n" }
};
//(1)テキストモードでファイル書き込み
//テキスト書き込みモードでファイルをオープン
err_no = fopen_s(&fp, csPath, "wt");
if (err_no != 0) {
csErr.Format("ファイルオープン(書き込みモード)に失敗しました。¥n%s",csPath);
AfxMessageBox(csErr, MB_ICONSTOP);
return (-1);
}
//ファイルに書き込み
for (i = 0; i < 4; i++)
{
//fwrite(buffer,size,count,stream)
//buffer : 書き込むデータへのポインター
//size : 書き込むサイズ(バイト単位)
//count : 書き込み回数
//stream : FILE構造体へのポインター
//戻り値 : エラーが発生した場合はcount(書き込み回数)未満
if ((iret = fwrite(irohauta[i], strlen(irohauta[i]), 1, fp)) == 0) {
csErr.Format("ファイル書き込み中にエラーが発生しました。¥n%s",csPath);
AfxMessageBox(csErr,MB_ICONSTOP);
fclose(fp);
return (-1);
}
//fputsを使用しても同様の書き込みができます
//iret = fputs(irohauta[i], fp);
}
//開いているファイルをすべて閉じます(本サンプルでは1ファイル)
//戻り値(numclosed)は閉じたファイルの数です
numclosed = _fcloseall();
//(2)テキストモードでファイル追記
//テキスト追記モードでファイルをオープン
err_no = fopen_s(&fp, csPath, "at");
if (err_no != 0) {
csErr.Format("ファイルオープン(追記モード)に失敗しました。¥n%s", csPath);
AfxMessageBox(csErr, MB_ICONSTOP);
return (-1);
}
//ファイルに書き込み(追記)
for (i = 4; i < 8; i++)
{
if ((iret = fwrite(irohauta[i], strlen(irohauta[i]), 1, fp)) == 0) {
csErr.Format("ファイル書き込み中(追記中)にエラーが発生しました。¥n%s", csPath);
AfxMessageBox(csErr, MB_ICONSTOP);
fclose(fp);
return (-1);
}
}
//開いているファイルを閉じます
numclosed = _fcloseall();
//(3)ファイル読み込み
//読み込みモードでファイルをオープン
char buf[MAX_LEN];
CString cbuf,cwk;
//改行がcrlf(0x0D0A)のファイルを読み込む際は
//そのまま読み込んでくれる"rb"が個人的に好みです("r"だと0x0Dが除かれます)
err_no = fopen_s(&fp, csPath, "rb");
if (err_no != 0) {
csErr.Format("ファイルオープン(読み込みモード)に失敗しました。¥n%s", csPath);
AfxMessageBox(csErr, MB_ICONSTOP);
return (-1);
}
//ファイル全体を一気に読み込むときはfreadが便利です
//bufにはファイル全体を読み込む十分なサイズが必要です
TRACE("¥n◎freadでの読み込み結果¥n");
while (!feof(fp)) {
ZeroMemory(&buf, MAX_LEN);
if ( (iret = fread(&buf, 1, sizeof(buf), fp)) == 0 ) break;
//読み込みバッファを表示
TRACE("%s",buf);
}
//ファイルの先頭にポインタを移動
fseek(fp, 0L, SEEK_SET);
//行単位でテキストファイルを読み込む時はfgetsが便利です
//bufには1行を読み込む十分なサイズが必要です
TRACE("¥n◎fgetsでの読み込み結果¥n");
ZeroMemory(&buf, MAX_LEN);
while (fgets(buf, sizeof(buf), fp) != NULL) {
//読み込みバッファを表示
TRACE("%s", buf);
ZeroMemory(&buf, MAX_LEN);
}
//開いているファイルを閉じます
numclosed = _fcloseall();
}
}
else
{
//〜〜中略〜〜
}
return nRetCode;
}
よろしければポチッと押してください
]]>
'//DLLの参照を宣言
Private Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwAccess As Long, ByVal fInherit As Long, _
ByVal IDProcess As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" ( _
ByVal hProcess As Long, ByRef lpdwExitCode As Long) As Long
'//定数定義
Private Const PROCESS_QUERY_INFORMATION = &H400&
Private Const STILL_ACTIVE = &H103&
'********************************************
'アプリケーションの終了を待ちます
'ペイント(mspaint.exe)を終了させるとメッセージを出力します
'********************************************
Sub アプリケーションの終了を待つ()
Dim lProcessID As Long, hProcess As Long
Dim dwExitcode As Long
Dim lret As Long
'//アプリケーションの起動
'//Shellの第1引数で指定したプログラムが存在しないときの実行エラーを回避してエラーメッセージを出力する
On Error Resume Next
lProcessID = Shell("mspaint", vbNormalFocus)
If Err <> 0 Then
'実行ファイルが存在しない時はエラーメッセージを出力する
MsgBox "プログラムの起動エラーです(Shell)", vbExclamation
Exit Sub
End If
On Error GoTo 0
'//実行したプログラムのプロセスハンドルを取得
'//PROCESS_QUERY_INFORMATION:GetExitCodeProcess関数がこのプロセスのハンドルを使うことを認める
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 1, lProcessID)
'//何らかの理由でプロセスハンドル取得でエラーが発生した
If hProcess = 0 Then
'VBAを起動しているエクセルをアクティブにする
AppActivate Application.Caption
MsgBox "プログラムのプロセスハンドル取得エラーです(OpenProcess)", vbExclamation
Exit Sub
End If
'//終了ステータス(dwExitcode)の監視
'//対象プログラムが実行中のとき終了ステータスはSTILL_ACTIVE(&H103)
Do
'オペレーティングシステムに制御を渡す
DoEvents
'プロセスの終了ステータスを取得
lret = GetExitCodeProcess(hProcess, dwExitcode)
'何らかの理由でGetExitCodeProcessが失敗した
If lret = 0 Then
CloseHandle hProcess
MsgBox "プログラムの終了ステータス取得エラーです(GetExitCodeProcess)", vbExclamation
Exit Sub
End If
Loop While (dwExitcode = STILL_ACTIVE)
'//終了後の処理
MsgBox "mspaintは正常に終了しました", vbInformation
End Sub
よろしければポチッと押してください
]]>
//MsgList.h
//メッセージデータを格納するヘッダーファイル(CSVファイル等で切り出してもよい)
#pragma once
/***********************************************************
独自(オリジナル)メッセージ定義
(1)要素
iCode : コード
cTitle : メッセージ
cMsg : メッセージ詳細
(2)メッセージ詳細の$1$から$3$は置換対象の文字列とする(最大3つまで)
(3)メッセージ詳細の改行は「¥r¥n」をセットする
***********************************************************/
static const struct {
unsigned int iCode;
char cTitle[128];
char cMsg[1024];
}MsgList[] = {
{ 101,"在庫ファイルオープンエラー","在庫ファイル($1$)が開けませんでした。¥r¥n書き込みを続行するにはファイルを閉じて再度処理を実行してください。" },
{ 102,"レコードの種別が不明です","ファイル($1$)に不正なレコードが見つかりました。¥r¥n$2$に問い合わせを行ってください。" },
{ 103,"処理が正常に終了しました","売上データ保存先:$1$¥r¥nレコード総数:$2$件¥r¥n未収金データ:$3$件" },
{ 104,"売上管理レコードの商品コードが不正です","現在取り扱いを中止している商品コード($1$)が見つかりました。¥r¥n処理を継続する場合は$2$に問い合わせを行ってください。" },
//データエンドマークとして末尾にコード=0をセット(読み込み終了判定用)
{ 0 },
};
//MsgBoxDlg.cpp
//[メッセージ表示]押下イベントを追加しておく
//インクルードファイル追加
#include "MessageShow.h"
#include "MsgList.h"
//MessageShow.h
//インクルードファイル追加
#include "MsgList.h"
//MessageShow.cpp
//OnInitDialogをクラスウィザードより追加しておく
//インクルードファイル追加
#include "MsgBox.h"
よろしければポチッと押してください
]]>よろしければポチッと押してください
]]>
//DropFile.h
//複数ファイル(フォルダ)がドロップされた時のためにパスを格納する配列(csdrop)を用意
//DropFile.cpp
//ドロップされた時の動作を記載
//DropSampleDlg.cpp
//エディットボックス、リストボックスをドロップされたパスで更新する
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>
'********************************************
'バイナリファイルの入出力テスト メインプログラム
'********************************************
Sub BinaryMain()
Dim strFile As String
'//ファイル名を生成
strFile = ThisWorkbook.Path & "¥binaryTest.dat"
'//全て(数式、文字列、書式、コメント、アウトライン)クリア
Cells.Select
Selection.Clear
Selection.Font.Name = "MS ゴシック"
Selection.Font.Size = 12
Range("A1").Select
'//バイナリデータをファイルへ書き込み(テストデータファイルを作成)
Call WriteBinaryFile(strFile)
'//バイナリファイルを読み込み(テストデータファイルを読み込み)
Call ReadBinaryFile(strFile)
End Sub
'********************************************
'バイナリデータをテストファイルに出力
'********************************************
Sub WriteBinaryFile(ByVal strfil As String)
'//バイナリファイルの1バイト毎の入出力にはByte型を用いる
Dim buff(499) As Byte
Dim i As Integer
Dim fp As Long
'//書き込みデータをセット(500バイトのテストデータを用意)
For i = 0 To 499
buff(i) = (i Mod 256)
Next
'//FreeFile関数で使用可能なファイル番号を割り当て
fp = FreeFile
'//ファイルが存在する場合は指定アドレスが上書きされるだけのため
'//書き込み前にファイルを削除するか中身を一旦クリアする
Open strfil For Output As #fp
Close (fp)
'//ファイルオープン(バイナリ書き込みでオープン、ファイルが存在しない場合は新規作成)
'//Openステートメントを用いてファイルの入出力を行います
'//モードに下記のいずれかが指定されていればファイルが存在しない場合、新規作成されます
'//追加モード(Append)、バイナリモード(Binary)、出力モード(Output)、ランダムアクセスモード(Random)
'//※https://msdn.microsoft.com/ja-jp/library/office/gg264163.aspx
Open strfil For Binary Access Write As #fp
'//ファイルに書き込み(ファイル先頭からの書き込みを明示)
Put #fp, 1, buff
'//ファイルを閉じる
Close (fp)
End Sub
'********************************************
'テストファイルからバイナリデータを読み込み
'********************************************
Sub ReadBinaryFile(ByVal strfil As String)
Dim buff() As Byte
Dim fp As Long
Dim filesize As Long, NowLoc As Long
Dim idx As Long, gyo As Long
Dim strBinary As String
'//FreeFile関数で使用可能なファイル番号を割り当て
fp = FreeFile
'//ファイルを開く
Open strfil For Binary As #fp
'//ファイルサイズ分の読み込み領域を確保して読み込む場合の実装例
'ReDim buff(FileLen(strfil))
'Get #fp, 1, buff
'//実装例ここまで
'//ヘッダ情報をシートに出力
Cells(1, 1) = " 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "
Cells(2, 1) = "---------------------------------------------------------"
'//ファイルの終端まで指定サイズ(最大16バイト)繰り返し読み込む
gyo = 3
Do While NowLoc < LOF(fp)
'//最大16バイト分の領域を確保し初期化
If (LOF(fp) - NowLoc) >= 16 Then
'//残りのファイルサイズが16バイト以上のとき
ReDim buff(15)
Else
'//最終読み込み時(497バイト〜500バイト目)は残りのファイルサイズが16未満
ReDim buff(LOF(fp) - NowLoc - 1)
End If
'//データを読み込み
Get #fp, , buff
'//表示用のアドレスを生成("00000000"とHexの戻り値を連結した文字列の右から8文字)
strBinary = Right("00000000" & Hex(NowLoc), 8) & " "
'//現在位置をを保持する(ループBreak判定用)
NowLoc = Loc(fp)
'//出力文字列を生成
For idx = 0 To UBound(buff)
strBinary = strBinary + Right("00" & Hex(buff(idx)), 2) + " "
Next
'//シートの1列目に結果を表示
Cells(gyo, 1) = strBinary
gyo = gyo + 1
Loop
'//ファイルを閉じる
Close (fp)
End Sub
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>(3)世界いろいろ雑学ランキング(データの出典:外務省ホームページ)の内容をリストボックスに表示します
<サンプルデータ>
外務省ホームページの「世界いろいろ雑学ランキング」より下記データを使用しました
・世界の高い山(http://www.mofa.go.jp/mofaj/kids/ranking/mountain.html)
・人口の多い国(http://www.mofa.go.jp/mofaj/kids/ranking/jinko_o.html)
・世界の長い川(http://www.mofa.go.jp/mofaj/kids/ranking/river.html)
・世界の広い湖(http://www.mofa.go.jp/mofaj/kids/ranking/lake.html)
データの出典:外務省ホームページ「世界いろいろ雑学ランキング」
http://www.mofa.go.jp/mofaj/kids/ranking/index.html
<使い方>
(1)ユーザフォームを追加
(ユーザフォームのHeightプロパティを316にセット)
(2)ユーザフォームに下記を追加(プログラムで使用する赤枠内のみ記載)
・コンボボックス:cboSelect
・表示⇔非表示 切り替えボタン:btnView
・URL表示ラベル:lblUrl
・ランキングデータ表示リストボックス:listResult
(ColunmCountを3、Heightプロパティを175に設定)
(3)フォームにソース全体を貼り付けてください(フォームを右クリック > コードの表示)
(4)「ユーザフォームの表示()」を呼び出すとフォームが表示されます
<イメージ>
リストボックスが非表示のとき(PropertyがFalse)
リストボックスが表示されているとき(PropertyがTrue)
'//ランキング格納構造体定義
よろしければポチッと押してください
]]>
<その他(汎用ポンタは加減算できないことの確認)>
おまけソースでポインタの加算処理サンプルを入れました(62〜69行)
汎用ポインタはポインタの加減算ができませんがキャストすると通常のポインタと同じように加減算できます
<使い方>
1.MFCアプリケーションのコンソールベースでプロジェクトを作成
2.構成プロパティ > 全般 > 文字セット で「マルチバイト文字セットを使用する」を選択
3.ヘッダファイルに構造体定義とデータセット処理(83行目以降)を貼り付ける
4.ChechBranch関数をCPPファイルに張り付ける(43〜81行目)
5.ChechBranch関数のプロトタイプ宣言をする(1〜3行目)
6.Main関数からの呼び出し部を張り付ける(5〜41行目)
//プロトタイプ宣言
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>
よろしければポチッと押してください
]]>
<イメージ>
BROWSEINFO構造体にBIF_NEWDIALOGSTYLE(新規フォルダ作成できる)を指定した場合とBIF_RETURNONLYFSDIRS(ファイルシステムのディレクトリのみ選択できる)を指定した場合のダイアログ
他にもいろいろオプションがありますので試してみてください
msdnは英語ページしかないみたいです
よろしければポチッと押してください
]]>