ホーム » 2024 » 6月

月別アーカイブ: 6月 2024

2024年6月
 1
2345678
9101112131415
16171819202122
23242526272829
30  

カテゴリー

アーカイブ

ブログ統計情報

  • 86,076 アクセス


robocopy エラー 87

IO DATA SSPA-USC500K が手に入ったので,テストを兼ねてソースなどをバックアップ.
アイ・オー・データ ポータブルSSD SSPA-USC500K
自前の「ディレクトリ以下のコピー」ツールでコピーしていると…

100%      新しいファイル                    1300        Vxx_P_A_.hxx
2024/06/23 15:44:41 エラー 87 (0x00000057) ファイル属性を変更しています \\DS220\Public\Document\Develop\_.SRC\__Iwao\P_A_gnsa.hxx
パラメーターが間違っています。
5 秒間待機しています... 再試行しています...

robocopy エラー 87 (0x00000057) ファイル属性を変更しています    
パラメーターが間違っています。
全てのファイルがこの様になるわけではない.
原因は,恐らくコピー先が exFAT のため?
ちゃんと調べたわけではないが,更新日時が古い(最近編集していない)ファイルでエラーになる模様.
これらのファイルは,昔 NT サーバなどで管理していたものを NAS に移して運用している.
その後,その NAS 上のものを編集する様になり,更新したものはエラーにはなっていない?
コピーはできているのと,同じコマンドの再実行ではエラーにはならないのでこのままとする.


エラーになったファイルは「作成日時」と「アクセス日時」がコピーしたタイミングに更新されてしまっている.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

::ShellExecute

「インデックスのオプション」を開くために ::ShellExecute などから開けないかと…
検索するとコマンドプロンプトなどで「control.exe /name Microsoft.IndexingOptions」とすれば良いことがわかった.


この動作の cpp のコード.

CString	Error_FormatMessage(const DWORD error)
{
	CString	message ;
	LPVOID	lpMessageBuffer = NULL ;
	if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
			NULL,error,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
			(LPTSTR)&lpMessageBuffer,0,NULL)) {
		message = LPTSTR(lpMessageBuffer) ;
		::LocalFree(lpMessageBuffer) ;
		}
	return	message ;
	}
void CShellEDlg::OnExecute() 
{
	UpdateData(TRUE) ;
	HINSTANCE hInst = ::ShellExecute(this->GetSafeHwnd(),m_StrOper,m_StrFile,m_StrPara,NULL,SW_SHOW) ;
	if (UINT64(hInst) > 32)	{	return ;	}
	DWORD	error = ::GetLastError() ;
	CString	str ;
	{
		str.Format(_T("%d\r\n%d"),DWORD(hInst),error) ;
		str += _T("    ") + ::Error_FormatMessage(error) ;
		str += _T("\r\n") + m_StrOper ;
		str += _T("\r\n") + m_StrFile ;
		str += _T("\r\n") + m_StrPara ;
		}
	AfxMessageBox(str) ;
	}

CShellEDlg::OnExecute()
ShellE  メンバ変数
ShellE.exe
https://itl.mish.work/i_Tools/Doc/blog/vc/ShellE.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

SetWindowPos で最前面に

以前から CWnd::SetWindowPos などを使用してウィンドウを最前面にしているツールがいくつかある.
ほとんどの場合これでうまくいっているが,先日テストしていて最前面に移動しない現象を確認.


2 つの exe があり,A.exe から B.exe を起動している.
B.exe はダイアログベースで,そのウィンドウを A.exe のウィンドウより前面に表示するもの.


Spy++ で見ると最前面に移動できた時は WS_EX_TOPMOST がある.
WS_EX_TOPMOST
が,うまくいかない場合には WS_EX_TOPMOST がない状態.


いろいろと操作してみたが,なかなか現象が絞れなかった.
結局は B.exe を起動する時,他のウィンドウにフォーカスが移っている?と,最前面にならないみたい.
B.exe の起動をエクスプローラなどから行い,ウィンドウが表示される前にブラウザなどに切替えると最前面にならない.


今回対象のものは,最前面に移動しなくても問題ないと思われるのでこのままとする.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CXxxxDlg::OnCreate が 2 回

「ある操作を行ったとき exe が 2 つ起動する」と報告があった.
言い訳になるが,通常この動作は年に 2 回程度しか通らないもの.また,他の操作により通らないこともある.
その条件になる様に環境を設定して試すと,確かに…


その部分のコードは,何年も変更はしていない.
いろいろと動作を確認していると,VC 10 以前では問題ないが,11 以降で 2 つ起動することがわかった.


その動作の部分のみを抜き出して動作を試した.

int CT_DlG_1Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	// TODO:  ここに特定な作成コードを追加してください。
	{
		HWND	HWnd = NULL ;
		{
			CWnd*	mainWnd = AfxGetMainWnd() ;
			if (mainWnd != NULL) {
				HWnd = mainWnd->GetSafeHwnd() ;
				}
			}
		HINSTANCE  hInst = ::ShellExecute(HWnd,NULL,_T("NotePad.exe"),NULL,NULL,SW_SHOWNORMAL) ;
		return	-1 ;
		}
	return 0;
	}

CXxxxDlg::OnCreate が 2 回呼ばれる?
MFC の動作が変わったのか,CXxxxDlg::OnCreate が 2 回呼ばれるようになったみたい.
https://itl.mish.work/i_Tools/Doc/blog/vc/TDlg0614.zip


2 回目に呼ばれた時は,何もしないで return -1 とする様に変更予定.

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

高 DPI 環境の CToolBar

複数のツールバーに対応するために CBitmap を new で生成する様に.
そのために新たに作成しようかと思ったが,既存のままでも良さそうなのでそれを少し修正.
LateDelete


また,次の様に予めボタンの背景を変更してみたが,うまくいかなかった.

{
	CDWordArray	orgBits ;
	DWORD		orgBmpSize = bm.bmWidthBytes * bm.bmHeight ;
	orgBits.SetSize(orgBmpSize) ;
	DWORD		orgBitsSize = tb_img.GetBitmapBits(orgBmpSize,orgBits.GetData()) ;
	for (DWORD index=0 ; index<orgBitsSize ; index++) {
		if (orgBits[index] == 0xc0c0c0) {
			orgBits[index] = col3D ;
			}
		}
	tb_img.SetBitmapBits(orgBitsSize,orgBits.GetData()) ;
	}

何かの手順が違っているみたいで,環境により?うまくいっている様に見えることもある.


https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0611.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CToolBar ボタン画像

先日の内容で残っているのが,ボタン画像の背景の色.
リソースエディタで 0xC0C0C0 を指定している所が,ボタンの色(::GetSysColor(COLOR_3DFACE))にならない.
Toolbar  IDR_MAINFRAME
何年も前に作成したコードを見ると,0xC0C0C0 を COLOR_3DFACE に置き換えている部分がある.
それでMFC のコード afxtoolbarimages.cpp を眺めていると CMFCToolBarImages::TransparentBlt があった.
その中で ::TransparentBlt を呼出している.
先日のコードの次の部分を ::TransparentBlt に変更してテストすると,
dstDC.StretchBlt(0,0,imageSize.cx,imageSize.cy,&srcDC,0,0,org_size.cx,org_size.cy,SRCCOPY) ;
::TransparentBlt(dstDC.GetSafeHdc(),0,0,imageSize.cx,imageSize.cy,
       srcDC.GetSafeHdc(),0,0,org_size.cx,org_size.cy,0xC0C0C0) ;
::TransparentBlt  (...,0xC0C0C0)
0xC0C0C0 の部分が描画されていない(透明になっている)ことが確認できたので,
dstDC.FillSolidRect(0,0,imageSize.cx,imageSize.cy,0xf0f0f0) ;
::TransparentBlt(dstDC.GetSafeHdc(),…,0xC0C0C0) ;
FillSolidRect
	::TransparentBlt
::SetStretchBltMode(…,HALFTONE) が効かない?
仮の DC を用意して ::TransparentBlt(そのまま) してそれを ::StretchBlt(リサイズ) の様にしてもダメだった.
TransparentBlt HALFTONE で検索したがあまり有用な情報は引っ掛からなかった.
リサイズして転送する(StretchBlt)前に CBitmap::GetBitmapBits で取り出し 0xC0C0C0 を書き換えるしかないか?


https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0610.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CToolBar ボタンのリサイズ

リサイズ部分を組み込んでみたが
CToolBar SetBitmap
ボタン画像の位置がズレている,DDB に対する操作が何か違っている.


試しに,新しいボタン画像サイズを次の様に求めるとそれなりの高さになった.
newImgSize.cy = newBtnSize.cy – 7 ;
newImgSize.cy = newBtnSize.cy - 7 ;
newImgSize.cx = newBtnSize.cx – 7 ;
newImgSize.cy = newBtnSize.cy – 6 ;
これでサイズは良さそう.
newImgSize.cx =(newBtnSize.cx - 7) * btnCount ;

{
	CSize	imageSize    = newImgSize ;
		imageSize.cx*= btnCount ;
	static	CBitmap	newImg ;	//  CBitmap* newImg = new CBitmap ; 
	{
		CBitmap	tb_img ;
		tb_img.LoadBitmap(idr) ;
		{
			BITMAP	bm = {0} ;  tb_img.GetBitmap(&bm) ;
			CSize	org_size = CSize(bm.bmWidth,bm.bmHeight) ;
			CDC*	wndDC = toolBar->GetDC() ;
			newImg.CreateCompatibleBitmap(wndDC,imageSize.cx,imageSize.cy) ;
			CDC	srcDC ;     srcDC.CreateCompatibleDC(wndDC) ;
			CDC	dstDC ;     dstDC.CreateCompatibleDC(wndDC) ;
			CBitmap*oldSrcBmp = srcDC.SelectObject(&tb_img) ;
			CBitmap*oldDstBmp = dstDC.SelectObject(&newImg) ;
			::SetStretchBltMode(dstDC.GetSafeHdc(),HALFTONE) ;
			dstDC.StretchBlt(0,0,imageSize.cx,imageSize.cy,
				&srcDC,0,0,org_size.cx,org_size.cy,SRCCOPY) ;
			srcDC.SelectObject(oldSrcBmp) ;
			dstDC.SelectObject(oldDstBmp) ;
			}
		}
	toolBar->SetBitmap(newImg) ;
	}

static CBitmap newImg としているため,複数のツールバーには対応していません.
CBitmap* newImg = new CBitmap の様にして終了時開放する必要があります.


https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0607.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CBitmap のコピー

次の所を参考に CBitmap のリサイズ …
How do you scale a CBitmap object?
CBitmap のリサイズでうまくない
1 回はリサイズできているが,コピー動作の部分が違っているみたいで正しく表示できない.
検索してみたがあまりわかりやすいコードに引っ掛からなかった.
Copilot で問合わせると

// 元のビットマップ
CBitmap originalBitmap;

// ... (originalBitmap を適切に初期化)

// コピーするビットマップ
CBitmap copiedBitmap;

// 元のビットマップの情報を取得
BITMAP bitmapInfo;
originalBitmap.GetBitmap(&bitmapInfo);

// コピーするビットマップを作成
copiedBitmap.CreateBitmap(bitmapInfo.bmWidth, bitmapInfo.bmHeight, bitmapInfo.bmPlanes, bitmapInfo.bmBitsPixel, NULL);

// 元のビットマップのビットを取得
BYTE* pBits = new BYTE[bitmapInfo.bmWidthBytes * bitmapInfo.bmHeight];
originalBitmap.GetBitmapBits(bitmapInfo.bmWidthBytes * bitmapInfo.bmHeight, pBits);

// コピーするビットマップにビットを設定
copiedBitmap.SetBitmapBits(bitmapInfo.bmWidthBytes * bitmapInfo.bmHeight, pBits);

// メモリを解放
delete [] pBits;

関数として書き直し.

CBitmap*	Copy_CBitmap	(CBitmap* src)
{
	CBitmap*	dst = new CBitmap ;
	BITMAP	bm ;
	src->GetBitmap(&bm) ;
	dst->CreateBitmap(bm.bmWidth,bm.bmHeight,bm.bmPlanes,bm.bmBitsPixel,NULL) ;
	BYTE*	pBits = new	BYTE[bm.bmWidthBytes*bm.bmHeight] ;
	src->GetBitmapBits(bm.bmWidthBytes*bm.bmHeight,pBits) ;
	dst->SetBitmapBits(bm.bmWidthBytes*bm.bmHeight,pBits) ;
	delete[]	pBits ;
	return	dst ;
	}

何とかコピーを表示できた.
CBitmap のコピー
https://itl.mish.work/i_Tools/Doc/blog/migrate/T_CB0606.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

mfc140ud.dll が見つからない …

「mfc140u.dll が見つからない…」の場合は
Microsoft Visual C++ 再頒布可能パッケージ


VC 2019 でデバッグビルドして実行すると,
—————————
Test.exe – システム エラー
—————————
mfc140ud.dll が見つからないため、コードの実行を続行できません。プログラムを再インストールすると、この問題が解決する可能性があります。
—————————
OK
—————————
VCRUNTIME140D.dll が見つからないため、コードの実行を続行できません。
ファイル名の所は MSVCP140D.dll などもある.
また exe は VC 2015 以降でデバッグビルドしたもの.


原因はわかっている.先日 VC 2022 のアップデートがあった.
その時 Win11 環境はうまくできたが Win10 環境では何故か失敗したため.
Microsoft.VisualCpp.Redist.14 をインストールできませんでした
どうしたものか…

「VS Installer」の「VS 2022」で「変更」を選択,そのまま進めるとダウンロード,インストールが始まった.
「VS Installer」の「VS 2022」で「変更」を選択
「修復」の方が良かったみたいだが …


「再起動が必要」の画面になり,その前にデバッグ版 exe を試すとうまく起動した.
「再起動が必要」

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

CBitmap の表示

ツールバーのビットマップをリサイズするために CBitmap を調べ始めた.
Inside VC++ Version 5 を参考に次の様に書いてみた.
プログラミング Visual C++ .NET では省かれている?

void CT_CBmpView::OnDraw(CDC* pDC)
{
//	CT_CBmpDoc* pDoc = GetDocument();
//	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	{
		CDC 	dc_mem ;	dc_mem.CreateCompatibleDC(pDC) ;
		CBitmap	bitmap ;	bitmap.LoadBitmap(IDR_MAINFRAME) ;
		BITMAP	bm = {0} ;	bitmap.GetBitmap(&bm) ;
		{
			CRect	rect(0,0,0,0) ;
			GetClientRect(&rect) ;
			rect.DeflateRect(100,100,200,200) ;
			::SetStretchBltMode(pDC->GetSafeHdc(),HALFTONE) ;
			dc_mem.SelectObject(&bitmap) ;
		//	pDC->BitBlt    (rect.left,rect.top,rect.right,rect.bottom,&dc_mem,0,0,SRCCOPY) ;
			pDC->StretchBlt(rect.left,rect.top,rect.right,rect.bottom,
				&dc_mem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY) ;
			}
		}
	}

そのまま貼り付けてテスト可能な様に View の OnDraw に書いています.
これを参考に実装する場合,リソースの読込み部分などは OnInitialUpdate などで行ってください.
CBitmap によるビットマップリソースの表示
https://itl.mish.work/i_Tools/Doc/blog/migrate/T_CB0604.zip


欲しかった CBitmap のリサイズのコードは次の所にあった.
How do you scale a CBitmap object?

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.

高 DPI 環境での CToolBar

vC 6 MFC プロジェクトを VC 2010 以降に更新すると,高 DPI 環境でツールバーがうまくない.
VC 10 以降でビルドした exe で,ツールバーが大きくならない
CMFCToolBar であれば OK .


個人的には 2005/06 に作成したコードを改良したものを使用している.
どこを参考にしたのかはちょっとわからない.
MFCによるWindows95プログラミング」や「INSIDE VISUAL C++ 5TH ED」などと思う.
それを簡単に利用できる様にできないかと…


コードは次の様な感じ.

BOOL	ToolBar__Resize	(CToolBar* toolBar,UINT idr)
{
	double	dpi_s = 1. ;
	{
		dpi_s = ::GetDPI_scale(toolBar->GetSafeHwnd()) ;	//  ::GetDpiForWindow() / 96.
		}
	if (dpi_s == 1.) {
		return	TRUE ;
		}
	CToolBarCtrl&	tbCtrl = toolBar->GetToolBarCtrl() ;
	CSize	btnSize(0,0) ;
	CRect	bdrRect(0,0,0,0) ;
	{	//  ボタンなどのサイズを取得
		DWORD	dwSize = tbCtrl.GetButtonSize() ;
		{
			btnSize.cx = LOWORD(dwSize) ;
			btnSize.cy = HIWORD(dwSize) ;
			}
		bdrRect        = toolBar->GetBorders() ;
		}
	CSize	newBtnSize = btnSize ;
	CRect	newBdrRect = bdrRect ;
	{	//  サイズを調整
		newBtnSize.cx    = int(btnSize.cx    *dpi_s) ;
		newBtnSize.cy    = int(btnSize.cy    *dpi_s) ;
		newBdrRect.left  = int(bdrRect.left  *dpi_s) ;
		newBdrRect.top   = int(bdrRect.top   *dpi_s) ;
		newBdrRect.right = int(bdrRect.right *dpi_s) ;
		newBdrRect.bottom= int(bdrRect.bottom*dpi_s) ;
		}
	{	//  サイズを指定
		tbCtrl.SetButtonSize(newBtnSize) ;
		toolBar->SetBorders(newBdrRect) ;
		}
	return	TRUE ;
	}

CToolBarCtrl  SetButtonSize
ツールバーボタンのビットマップのリサイズはまだ書換えができていない.
https://itl.mish.work/i_Tools/Doc/blog/migrate/Test0603.zip

Is this 投稿 useful? Useful Useless 0 of 0 people say this 投稿 is useful.