コンソール AP でレジストリ読み取り
コンソール AP で,レジストリを読み取るために以下の様な関数を用意した.
int Reg_GetInt (HKEY hKey,LPCTSTR subKey,LPCTSTR ent,const int defValue=0)
{
DWORD value = defValue ;
#ifdef _ATL_VER
{
CRegKey reg ;
reg.Open(hKey,subKey) ;
#if (_ATL_VER >= 0x700)
reg.QueryDWORDValue(ent,value) ;
#else
reg.QueryValue(value,ent) ;
#endif
}
#else
{
HKEY hSecKey = NULL ;
LONG openStatus = ::RegOpenKeyEx(hKey,subKey,0,KEY_READ,&hSecKey) ;
if (hSecKey == NULL) { return value ; }
DWORD type = REG_NONE ;
DWORD count = sizeof(DWORD) ;
LONG queryStatus = ::RegQueryValueEx(hSecKey,ent,NULL,&type,(LPBYTE)&value,&count) ;
::RegCloseKey(hSecKey) ;
}
#endif
return int(value) ;
}
*::Reg~ などのエラーチェックは省いている.
呼出すのはこんな感じ.
int value = ::Reg_GetInt(HKEY_CURRENT_USER,_T(“Software\\Iwao\\Test\\RegAcc”),_T(“T_RegKey_DW”)) ;
CWinApp::GetProfileInt などが使えないかとやってみたが,…
1. AfxGetApp() を呼びだしても,NULL で戻ってくる.
次の様に領域を確保.
CWinApp theApp;
2. SetRegistryKey(key) が直接呼びだせないので,
class C_SRK_WinApp : public CWinApp {
public:
void SetRegKey (LPCTSTR key) { SetRegistryKey(key) ; }
} ;
変数の確保は次の様に変更.
C_SRK_WinApp theApp ;
3. SetRegistryKey の中で ASSERT(m_pszAppName != NULL)
以下を追加して,CWinApp を初期化.
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0) ;
4. これで CWinApp::GetProfileInt は利用できるようになるが,CWinApp::m_pszProfileName が邪魔.
C_SRK_WinApp* app = (C_SRK_WinApp*)AfxGetApp() ;
int val = app->GetProfileInt(_T(“Test\\RegAcc”),_T(“T_RegKey_DW”),0) ;
HKCU\Software\Iwao\(m_pszProfileName)\Test\RegAcc となってしまう.
5. m_pszProfileName を _T(“”) とすることにより,意図した値を取得できる様にはなった.
C_SRK_WinApp* app = (C_SRK_WinApp*)AfxGetApp() ;
if (app != NULL) {
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0) ;
app->SetRegKey(_T(“Iwao”)) ;
free((void*)app->m_pszProfileName) ;
app->m_pszProfileName = _tcsdup(_T(“”)) ;
int val = app->GetProfileInt(_T(“Test\\RegAcc”),_T(“T_RegKey_DW”),0) ;
}
コンソール AP で CWinApp::GetProfileInt などを使うことは,やめ.
コンテキストメニューが表示されない
あるダイアログベースの exe をテストしていて,右クリックでメニューが表示されない現象となった.
ボタンによる動作のメニューは表示される.
デバッガで追いかけると,次の様なコードの CMenu::LoadMenu が FALSE となっていた.
void CXxxxDlg::PopupSingleSel(CPoint pt,CWnd *wnd)
{
CMenu menu ;
if (!menu.LoadMenu(IDR_SINGL_SEL)) { return ; }
CMenu* pPopup = menu.GetSubMenu(0);
…
}
ボタンによるメニュー表示は次のコード.
void CXxxxDlg::OnOther()
{
CMenu menu ;
if (!menu.LoadMenu(IDR_OTHER)) { return ; }
CMenu* pPopup = menu.GetSubMenu(0);
…
}
double -> long
double の値を long にキャストした時,VC 8 で思った動作ではなかったので調べてみた.
テストに使用したのは次の様な単純なコード.
// T_DtoI.cpp
#include <iostream>
int main(int argc, char* argv[])
{
double d8 = 1/7. ;
for (int index=0 ; index<25 ; index++) {
d8 = (d8 * 7) ;
__int64 i8 = __int64(d8) ;
long l4 = long(d8) ;
printf ((“%15g\t%25I64d\t%20I64x\t%15ld\t%15x\n”),d8,i8,i8,l4,l4) ;
}
return 0;
}
d8 の値を /7 と *7 としているのはあまり意味はない.
C:\Users\Iwao>\\DevXP\C_Drive\Temp\TestCPP\T_DtoI\Release.060\T_DtoI.exe 1 1 1 1 1 7 7 7 7 7 49 49 31 49 31 343 343 157 343 157 2401 2401 961 2401 961 16807 16807 41a7 16807 41a7 117649 117649 1cb91 117649 1cb91 823543 823543 c90f7 823543 c90f7 5.7648e+006 5764801 57f6c1 5764801 57f6c1 4.03536e+007 40353607 267bf47 40353607 267bf47 2.82475e+008 282475249 10d63af1 282475249 10d63af1 1.97733e+009 1977326743 75db9c97 1977326743 75db9c97 1.38413e+010 13841287201 339014821 956385313 39014821 9.6889e+010 96889010407 168f08f8e7 -1895237401 8f08f8e7 6.78223e+011 678223072849 9de93ece51 -381759919 e93ece51 4.74756e+012 4747561509943 45160b7a437 1622647863 60b7a437 3.32329e+013 33232930569601 1e39a5057d81 -1526366847 a5057d81 2.32631e+014 232630513987207 d39383266e87 -2094633337 83266e87 1.62841e+015 1628413597910449 5c908960d05b1 -1777531471 960d05b1 1.13989e+016 11398895185373144 287f3c1a5b27d8 442181592 1a5b27d8 7.97923e+016 79792266297612000 11b7aa4b87e16e0 -1199696160 b87e16e0 5.58546e+017 558545864083283968 7c05a810b72a000 192061440 b72a000 3.90982e+018 3909821048582987776 3642798750226000 1344430080 50226000 2.73687e+019 -9223372036854775808 8000000000000000 0 0 1.91581e+020 -9223372036854775808 8000000000000000 0 0 C:\Users\Iwao>\\DevXP\C_Drive\Temp\TestCPP\T_DtoI\Release.080\T_DtoI.exe 1 1 1 1 1 7 7 7 7 7 49 49 31 49 31 343 343 157 343 157 2401 2401 961 2401 961 16807 16807 41a7 16807 41a7 117649 117649 1cb91 117649 1cb91 823543 823543 c90f7 823543 c90f7 5.7648e+006 5764801 57f6c1 5764801 57f6c1 4.03536e+007 40353607 267bf47 40353607 267bf47 2.82475e+008 282475249 10d63af1 282475249 10d63af1 1.97733e+009 1977326743 75db9c97 1977326743 75db9c97 1.38413e+010 13841287201 339014821 -2147483648 80000000 9.6889e+010 96889010407 168f08f8e7 -2147483648 80000000 6.78223e+011 678223072849 9de93ece51 -2147483648 80000000 4.74756e+012 4747561509943 45160b7a437 -2147483648 80000000 3.32329e+013 33232930569601 1e39a5057d81 -2147483648 80000000 2.32631e+014 232630513987207 d39383266e87 -2147483648 80000000 1.62841e+015 1628413597910449 5c908960d05b1 -2147483648 80000000 1.13989e+016 11398895185373144 287f3c1a5b27d8 -2147483648 80000000 7.97923e+016 79792266297612000 11b7aa4b87e16e0 -2147483648 80000000 5.58546e+017 558545864083283968 7c05a810b72a000 -2147483648 80000000 3.90982e+018 3909821048582987776 3642798750226000 -2147483648 80000000 2.73687e+019 -9223372036854775808 8000000000000000 -2147483648 80000000 1.91581e+020 -9223372036854775808 8000000000000000 -2147483648 80000000
VC 7 , 7.1 は VC 6 と同等.VC 12 までは VC 8 と同等.
Mac 64 ビットでは,long が 64 ビットのため?そのままだと VC 6 と同等になる.
long を int として 32 ビットとすると VC 8 と同等.
ここまでは,long の範囲を超えたためと理解できるが,unsigned long の場合はまた動作が異なる.
long l4 = long(d8) ;
ULONG u4 = ULONG(d8) ;
printf ((“%15g %25I64d %20I64x %12ld %10x %12ld %10x\n”),d8,i8,i8,l4,l4,u4,u4) ;
今回表面化したバグは,次のコード.
long now_Tick = long(GetTickCount_s()*1000) ;
得た値を覚えておき,次のタイミングで 1 秒以上の開きがあるかを計測したかった.
最初の頃はわからなかったが,
先日 25 日(0x7FFFFFFF 2,147,483,647)を過ぎて 0x80000000 となってしまっていた.
MSDN 浮動小数点型からの変換
GetDIBits
GetDIBits を利用していて,最初うまく取れなかったのでメモ.
lpvBits に NULL が指定できるとのことなので,
::GetDIBits(hDC,hbm,0,bmap.bmHeight,NULL, &bmif,DIB_RGB_COLORS) ;
しかしうまく取れない.原因は,biSize の指定がされてなかったため.
bmif.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) ;
以下の様に,BITMAPINFO を求めてから,もう一度呼び出し情報は取れる様になった.
::GetDIBits(hDC,hbm,0,bmap.bmHeight,NULL, &bmif,DIB_RGB_COLORS) ;
if (::GetDIBits(hDC,hbm,0,bmap.bmHeight,&bits[0], &bmif,DIB_RGB_COLORS) != 0) {
….
}
が,bmif の部分を stack としていて,オーバーフローしている.
BITMAPINFO bmif ; memset(&bmif, 0, sizeof(BITMAPINFO)) ;
デバッグ用に,次の様に 0xfe で初期化して渡してみると
v_char bmif ; bmif.resize(sizeof(BITMAPINFO)+sizeof(RGBQUAD)*256,-2) ;
memset(&bmif[0],0, sizeof(BITMAPINFO)) ;
BITMAPINFO* pbmi = (BITMAPINFO*)&bmif[0] ;
00036C40 28 00 00 00 02 00 00 00 02 00 00 00 01 00 20 00 (............. . 00036C50 03 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ................ 00036C60 00 00 00 00 00 00 00 00 00 00 FF 00 00 FF 00 00 ................ 00036C70 FF 00 00 00 FE FE FE FE FE FE FE FE FE FE FE FE ................
どうも,1 回目の GetDIBits で,pbmi->bmiHeader.biCompression が BI_BITFIELDS となっている.
… the color table consists of three DWORD color masks that specify the red, … とある.
以下の様に,BI_RGB を再設定する様にした.
::GetDIBits(hDC,hbm,0,bmap.bmHeight,NULL, pbmi,DIB_RGB_COLORS) ;
pbmi->bmiHeader.biCompression = BI_RGB ;
if (::GetDIBits(hDC,hbm,0,bmap.bmHeight,&bits[0], pbmi,DIB_RGB_COLORS) != 0) {
….
}
HBM_Fn.hxx
i_DIB_Fn.hxx
MessageBar クラスと OpenMP
新しい Message クラスを使用して,OpenMP 対応の動作のテスト.
void CTSttBView::OnTestDrawBar2()
{
Message tmp ;
ElapseTick et ;
#define BAR_COUNT_2 1000000
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0 ; i<100 ; i++) {
Message bar ;
bar.SetBar (_T(“Test Message 1 M * 100”),BAR_COUNT_2,RGB(0,255,0)) ;
for (int index=0 ; index<BAR_COUNT_2 ; index++) {
bar.SetBarInc() ;
}
}
DWORD elapseT = et.GetElapse() ;
CString str ; str.Format(_T(“%.2f 秒”),elapseT/1000.) ;
AfxMessageBox(str) ;
}
1 億回 SetBarInc を呼出していて,10 秒程度だったのが,#pragma omp parallel for で 20 秒程度になってしまった.
inline bool MessageBase::SetBarInc (void)
{
if (GetBarMax() == 0) { return false ; }
if (GetBarCount() < GetBarMax()) { B_Counter++ ; }
else { B_Counter = 0 ; } // reset
IncCounterR() ;
{
long lastPos = long(100*(GetBarCount()-1)/GetBarMax()) ;
long new_Pos = long(100*(GetBarCount()-0)/GetBarMax()) ;
if (lastPos == new_Pos) { return true ; }
}
#ifdef _WINDOWS
#ifdef _MFC_VER
#ifdef _OPENMP
if (AfxGetMainWnd() == NULL) { return false ; }
#endif
#endif
#endif
return SetBarCount(B_Counter) ;
}
AfxGetMainWnd() を呼出す回数を減らすことにより,3 秒程度に.
デバッグビルドで C2061 ‘_DebugHeapTag_func’
以前(2014/04/25 の exe が存在する)は通っていたのに,…
------ ビルド開始: プロジェクト: BLCombi, 構成: Debug Win32 ------ ComPrj01.cpp c:\program files (x86)\microsoft visual studio 9.0\vc\include\xlocmon(283) : error C2061: 構文エラー : 識別子 '_DebugHeapTag_func' c:\program files (x86)\microsoft visual studio 9.0\vc\include\xlocmon(281): クラス テンプレート のメンバ関数 'size_t std::moneypunct<_Elem,_Intl>::_Getcat(const std::locale::facet **,const std::locale *)' のコンパイル中 with [ _Elem=char, _Intl=true ] c:\program files (x86)\microsoft visual studio 9.0\vc\include\xlocmon(908) : コンパイルされたクラスの テンプレート のインスタンス化 'std::moneypunct<_Elem,_Intl>' の参照を確認してください with [ _Elem=char, _Intl=true ] BLCombi - エラー 1、警告 1
------ ビルド開始: プロジェクト: BLCombi, 構成: Debug Win32 ------ ComPrj01.cpp c:\program files\microsoft visual studio 8\vc\include\xlocmon(273) : error C2061: 構文エラー : 識別子 '_DebugHeapTag_func' c:\program files\microsoft visual studio 8\vc\include\xlocmon(271): クラス テンプレート のメンバ関数 'size_t std::moneypunct<_Elem,_Intl>::_Getcat(const std::locale::facet **)' のコンパイル中 with [ _Elem=char, _Intl=true ] c:\program files\microsoft visual studio 8\vc\include\xlocmon(887) : コンパイルされたクラスの テンプレート のインスタンス化 'std::moneypunct<_Elem,_Intl>' の参照を確認してください with [ _Elem=char, _Intl=true ] BLCombi - エラー 1、警告 0
------ ビルド開始 : プロジェクト : BLCombi, 構成 : Debug Win32 ------ ComPrj01.cpp c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xlocmon(249) : error C2061: 構文エラー : 識別子 '_DebugHeapTag' c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xlocmon(247): クラス テンプレートのメンバ関数 'size_t std::moneypunct<_Elem,_Intl>::_Getcat(const std::locale::facet ** )' のコンパイル中 with [ _Elem=char, _Intl=true ] c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xlocmon(828) : コンパイルされたクラスのテンプレートのインスタンス化 'std::moneypunct<_Elem,_Intl>' の参照を確認してください with [ _Elem=char, _Intl=true ] BLCombi - エラー 1、警告 0
------ ビルド開始 : プロジェクト : BLCombi, 構成 : Debug Win32 ------ ComPrj01.cpp c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xloctime(539) : error C2061: 構文エラー : 識別子 '_DebugHeapTag' c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\xloctime(539) : error C2143: 構文エラー : ';' が ')' の前にありません。 BLCombi - エラー 2、警告 0
VC 6 や VC 10 , 11 , 12 では 通る.
検索すると, #define new DEBUG_NEW の定義の様であるが,この ComPrj01.cpp でどうすべきかが不明.
本来は,ComPrj01.cpp でインクルードしているファイルを変更すべきなのだろうが,いい方法がわからない.
ComPrj01.cpp でインクルードしているものの順番を変更することで,通る様にはなった.
2024/11/11
https://dev.mish.work/wordpress/?s=C2061
コンボボックスで文字化け
「今まで CHS で使用していた環境を日本語に切替えたのに,一部 “漢字” で表示されたままになっている」と問合せ.
UNICODE.exe なので,MultiByte との変換の時には問題が発生することは知っていたが,…
メニューやダイアログのタイトルなどは問題ないが,コンボボックスで文字化けしていた.
「コントロールパネル」-「地域と言語」-「管理」タブ-「Unicode 対応…」-「システム ロケール…」が「日本語」でなかった.
UNICODE.exe でも,コンボボックスでは文字化けすることは知らなかったので,exe を作って調べてみた.
MBCS.exe .半角カタカナなども文字化けしてしまう.
UNICODE.exe .コードで追加している場合は,正しく表示される.
m_ComboD.AddString(_T(“1234567890”)) ;
m_ComboD.AddString(_T(“12345”)) ;
m_ComboD.AddString(_T(“ABCDEFGHIJ”)) ;
m_ComboD.AddString(_T(“ABCDE”)) ;
m_ComboD.AddString(_T(“あいうえお”)) ;
m_ComboD.AddString(_T(“亜意卯絵尾”)) ;
VC 2013 で同様に作成してみたが,
最初,リソースエディタで複数指定する方法がわからなかったが,セミコロンで区切れば OK .
コンボボックスの表示データを,リソースで指定している場合に文字化けしてしまう.
ComboBox.zip
これらに関して検索してみると,
UNICODEアプリケーションで文字化けが発生する
リソースファイルの文字列のUNICODE化
xcode + glut
「Command Line Tool」としてプロジェクトを作成.
「GLUT」を追加.
10.9 になったこと?により出力される次の様なワーニングをでない様にするために 10.8 に.
/Users/Iwao/…/main.cpp:116:2: ‘glutInit’ is deprecated: first deprecated in OS X 10.9
インクルードパス設定場所は,「Build Settings」−「Search Paths」−「Header Search Paths」
glut.h のインクルードは以下の様にしている.
#ifdef __APPLE_CC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
OpenGL Programing Guide
何年も前に買った本(1995年8月10日第4刷となってる)で,中に含まれるサンプルを実行できる様にしてみた.
OpenGL Programing Guide
サンプルのソースで,<gl\glut.h> のインクルードは最初に移動.
glut
opengl.org
GLUT and OpenGL Utility Libraries
GLUT – The OpenGL Utility Toolkit
Nate Robin’s GLUT for Windows page
glut32.dll は,system32 などへ.
glut.h は,~\Include\gl へ.
glut32.lib は,~\Lib へ.
セレクション
::glRenderMode(GL_SELECT) の後の ::glRenderMode(GL_RENDER) で,セレクションヒット数が得られる.
::glGetIntegerv(GL_RENDER_MODE) で現在のモードを取得可能.
セレクションバッファの内容
名前の深さ?
Z min
Z max
名前 …
2014/09/04
時間がかかったがなんとか GLUT ではできた.
2014/09/08
今度は,VXxxxView を使用した SDI.exe での手順.
ビューの OnDropFiles で,ファイルの種類により glRenderMode GL_SELECT , GL_RENDER を呼ぶ様に変更.
CMainFrame::OnDropFile で条件により CXxxxView::OnDropFile を呼び出し.
glGetIntegerv(GL_RENDER_MODE,…) で GL_SELECT が返ってこない.
wglMakeCurrent を呼んでなかったので,効果がなかった.
今度は,GL_SELECT にならない.GL_INVALID_OPERATION となる.
ヘルプにある様に,glSelectBuffer を呼んでなかった.
CPickSView::OnDropFiles
GetOpGLP()->MakeCurrent(TRUE) ;
if (…) {
::glSelectBuffer(BUFSIZE,selBuf) ;
::glRenderMode(GL_SELECT) ;
}
else {
::glRenderMode(GL_RENDER) ;
}
GetOpGLP()->MakeCurrent(FALSE) ;
2014/09/10
PickS.2014.09.09.zip
マウスの Y 方向の位置が合ってない.
その exe を Win 7 環境で動かすと,
デバッグ用に ::glGetIntegerv(GL_RENDER_MODE,…) のために GetOpGLP()->MakeCurrent(…) していた.
MakeCurrent(FALSE) で SwapBuffers を呼んでいる.
マウスの Y 方向は,縦長だと合っていそう.横長だとその長い分だけ Y 方向にずれている?
コの字型の平面方向で,座標はそれなりにとれている.::gluUnProject の z は Depth / 0xffffffff .
gulUnProject の y の与え方が違っていた.
viewPort[3] – pt.y としていたが,それではダメみたいで,GetClientRect の Height() としてうまくいってそう.
PickS.2014.09.10.zip
まだ ::gluPickMatrix の方がうまくできてない.
2014/09/11
平面図にして,1 つの直方体がウィンドウいっぱいに表示される状態で選択すると,
どうもピック領域のサイズが,ウィンドウの大きさになっているような感じ.
20 Picking and Using Selection 20. ピッキングとセレクションの使い方 を参考にしているが,…
::gluPickMatrix を呼ぶタイミングが悪かったのが原因.
ある程度予想はしていたが,OpGL::Projection の中のため,その関数を分割する必要がありそう.
その関数内の OpenGL の呼び出しは,
::glMatrixMode(GL_PROJECTION) ;
::glLoadIdentity() ;
// ここ
::glOrtho(r.l,r.r,r.b,r.t, zNear,zFar) ; / ::gluPerspective(deg(angle),aspect, zNear,zFar) ;
::glViewport((GLint)win.l,(GLint)win.b,(GLint)(win.r-win.l),(GLint)(win.t-win.b)) ;
glLoadIdentity() の後に ::gluPickMatrix を呼ばなければならない.
PickS.2014.09.11.zip
2014/09/18
汎用的なコードにするため,コードを見直しているがなかなか進まない.
例えば,マウスの移動で選択されているものを表示しようとすると,テクスチャありでは遅くて使えない.
また,その時の表示で PgonsA の描画を抜き出したコードだと何とか見れるが PartsA::Draw 相当だと遅い.
PickS.2014.09.18.zip
COleDataSource を利用した Drag
以前 DoDragDrop で少し調べたが,その時は途中になっていた.
その時の内容で,例えば CListBox に表示されてるファイルリストのすべてを,CListBox の外側でドラッグするすることはできる.
void CDragLBDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
CStringArray sa ;
::ToStringArray(FileNames,&sa) ;
::StringArrayToDoDragFiles(sa) ;
}
CListCtrl であれば,OnBegindragXxxx が利用できるので,
void CDragLVDlg::OnBegindragListFiles(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
{
CStringArray sa ;
for (int index=0 ; index<m_ListFiles.GetItemCount() ; index++) {
if (m_ListFiles.GetItemState(index,LVIS_SELECTED) == LVIS_SELECTED) {
tstring str = FileNames[index] ;
sa.Add(str.c_str()) ;
}
}
if (sa.GetSize() > 0) {
::StringArrayToDoDragFiles(sa) ;
}
}
*pResult = 0;
}
今回やりたかったのは,CListBox の項目のドラッグ.
ドラッグ部分は CListCtrl とほぼ同様となると思われるが,ドラッグ開始のタイミングが取れない.
CDragListBox と開始時の動きは似ているが,MFC のコードを見るとちょっと難しそう.
いろいろと検索すると,CListBox のサブクラス化で対応するみたいとわかったが,手順が...
動的なサブクラス化と言うらしい.
Inside Visual C++ には,囲み記事に CNonNumericEdit がある.
利用する手順はわかるが,作成する手順がわからない
今も利用はしている CView からの VXxxxView ファミリがあるが,10 年以上前で手順は覚えてない.
いろいろ探して「MFC クラスウィザード」を利用することがわかった.
今まで,よく見ていたダイアログなのに...
後は,WM_LBUTTONDOWN を処理する様にして,
void CMyListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
CListBox::OnLButtonDown(nFlags, point);
int sel = GetCurSel() ;
if (sel == LB_ERR) { return ; }
CString str ;
GetText(sel,str) ;
CStringArray sa ;
sa.Add(str) ;
::StringArrayToDoDragFiles(sa) ;
}
ダイアログに追加したリスボックスで,これを利用する様にダイアログのヘッダを修正.
MSDN CTRLTEST サンプル
テクニカル ノート 14
標準コントロールからのコントロールの派生
[MSVC] MFCを使用しての動的サブクラス化
Create Client Windows, Drag and Drop Between Listboxes
2014/08/11 追記
COleDataSource を利用して,他の AP に CF_HDROP で渡そうとすると,
—————————
Microsoft Visual C++ Debug Library
—————————
Debug Assertion Failed!
Program: …Documents\Visual Studio 2010\Projects\TestVC10\Debug\T_SC.exe
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp
Line: 43
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
—————————
中止(A) 再試行(R) 無視(I)
—————————
COleDataSource の使い方が間違っていた.
開放する時に delete ではうまくない.
データ オブジェクトとデータ ソース : 作成と破棄
モードレスダイアログの動作が,…
VC 7 以降,MDI AP のモードレスダイアログが独立して動作してしまう現象があった.
その AP は,VC 4 の頃作成したもので CMainFrame::OnCreate 内でモードレスダイアログを作成している.
VC 6 までは特に問題なかったが,VC 7 以降タスクバーにアイコンが 2 つ存在する状態になってしまっていた.
過去に何度か対応方法を調べたが,わからずそのままとなっていた.
今日別の事を調べていて,「モードレスダイアログで親子にならなくする」方法が目に留まった.
CDialog::Create で,デフォルトの NULL ではなく,GetDesktopWindow() を与えるというもの.
VC 7 AP のダイアログの情報を,Spy++ で見ると,親ウィンドウが (なし) になっている.
今度はデバッガで,Create の付近を追いかけると AfxGetMainWnd() で NULL がかえっている.
ThrdCore.cpp より
CWnd* CWinThread::GetMainWnd()
{
if (m_pActiveWnd != NULL)
return m_pActiveWnd;
if (m_pMainWnd != NULL)
return m_pMainWnd;
return CWnd::GetActiveWindow();
}
CXxxApp::InitInstance で以下の部分を修正.
CMainFrame* pMainFrame = new CMainFrame;
m_pMainWnd = pMainFrame; // ここを追加
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
CSplitterWnd – 2
SDI で,MDI の「新しいウィンドウを開く」で 4 つのビューを表示した様な動作が欲しかったので,調べてみた.
動的な分割ウィンドウである程度の所まではできそう.
1. MainFrm.h の CMainFrame に以下を追加. CSplitterWnd m_wndSplitter; virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); 2. CMainFrame::OnCreateClient の追加. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { { if (!m_wndSplitter.Create(this,2, 2,CSize(10, 10), pContext, WS_CHILD | WS_VISIBLE /* | WS_HSCROLL | WS_VSCROLL */ | SPLS_DYNAMIC_SPLIT)) { TRACE0("Failed to create split bar "); return FALSE; } return TRUE; } } スクロールバーを付加したくなかったので,6 つ目のウィンドウスタイルを変更している. テスト用に分割動作をコマンドとして実装. void CMainFrame::OnSplit() { if (IsSplit) { if (m_wndSplitter.GetColumnCount() > 1) { m_wndSplitter.DeleteColumn(1) ; } if (m_wndSplitter.GetRowCount() > 1) { m_wndSplitter.DeleteRow (1) ; } IsSplit = !IsSplit ; } else { CRect rect ; m_wndSplitter.GetClientRect(&rect) ; if (m_wndSplitter.GetColumnCount() == 1) { m_wndSplitter.SplitColumn(rect.Width ()/2) ; } if (m_wndSplitter.GetRowCount() == 1) { m_wndSplitter.SplitRow (rect.Height()/2) ; } IsSplit = !IsSplit ; } }
2 x 2 の分割ウィンドウのコントロールの ID (Spy++ で確認)
左上(0,0) E900 AFX_IDW_PANE_FIRST
右上(0,1) E901
左下(1,0) E910
右下(1,1) E911
ビューの OnDraw を以下の様に書き換えると
void CSpltWView::OnDraw(CDC* pDC) { int row = -1 ; int clm = -1 ; CMainFrame* mw = (CMainFrame*)AfxGetMainWnd() ; CSplitterWnd* sw = &mw->m_wndSplitter ; CString str ; if (sw->IsChildPane(this,&row,&clm)) { int id = sw->IdFromRowCol(row,clm) ; CString tmp1 ; tmp1.Format(_T("row = %d , clm = %d"),row,clm) ; CString tmp2 ; tmp2.Format(_T("IdFromRowCol = %04X"), id) ; str += tmp1 + _T("\r\n") ; str += tmp2 + _T("\r\n") ; } { UINT nID = GetDlgCtrlID() ; CString tmp ; tmp.Format(_T("GetDlgCtrlID = %04X"),nID) ; str += tmp + _T("\r\n") ; } { CWnd* pw = GetParent() ; CString tmp1 ; tmp1.Format(_T("Splitter = %08x "),sw->GetSafeHwnd()) ; CString tmp2 ; tmp2.Format(_T("Parent = %08x "),pw->GetSafeHwnd()) ; str += tmp1 + _T("\r\n") ; str += tmp2 + _T("\r\n") ; } CRect rect ; GetClientRect(rect) ; rect.top = rect.left = 10 ; pDC->DrawText(str,rect,0) ; }
MFC の ソースを眺めていると CView::GetParentSplitter があったので,間接的にはそれを使えば良さそう.
ビューでどの位置かを求めるだけなら, short texNo = 0 ; { UINT nID = GetDlgCtrlID() ; switch (nID) { case AFX_IDW_PANE_FIRST + 0x00 : texNo = 1 ; break ; case AFX_IDW_PANE_FIRST + 0x01 : texNo = 2 ; break ; case AFX_IDW_PANE_FIRST + 0x10 : texNo = 3 ; break ; case AFX_IDW_PANE_FIRST + 0x11 : texNo = 4 ; break ; } }
‘THIS_FILE’ がシンタックスエラーを…
今まで通っていたプロジェクトで,
ComPrj03.cpp
c:\…\memory(16) : error C2061: 構文エラー : 識別子 ‘THIS_FILE’ がシンタックスエラーを起こしました。
c:\…\memory(17) : error C2091: 関数は関数を返せません。
c:\…\memory(17) : error C2809: ‘operator new’ に仮引数リストがありません。
c:\…\memory(20) : error C2954: テンプレートの定義はネストできません。
cl.exe の実行エラー
ComPrj03.obj – エラー 4、警告 0
ソースの先頭付近に #include <memory> を追加.
#include “StdAfx.h”
#include “ComPrj00.hpp”
#include <memory>
2019/01/18
--------------------構成: MkZIP2 - Win32 Release-------------------- コンパイル中... MkZIP2.cpp リンク中... MkZIP2.exe - エラー 0、警告 0 --------------------構成: MkZIP2 - Win32 Debug-------------------- コンパイル中... MkZIP2.cpp c:\program files\microsoft visual studio\vc98\include\memory(16) : error C2061: 構文エラー : 識別子 'THIS_FILE' がシンタックスエラーを起こしました。 c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2091: 関数は関数を返せません。 c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2809: 'operator new' に仮引数リストがありません。 c:\program files\microsoft visual studio\vc98\include\memory(20) : error C2954: テンプレートの定義はネストできません。 cl.exe の実行エラー MkZIP2.exe - エラー 4、警告 0
#include “stdafx.h”
#include “MkZIP2.h”
#include <ShlObj.h>
#import <Shell32.dll> // named_guids
//#include <memory>
エラーになるのはデバッグ版のビルド.リリース版では通る.
#include <memory> を有効に.
2023/03/24
#define new DEBUG_NEW より後にインクルードしているとうまくない error C2061 , C2091 , C2809 , C2556