Iwao Dev

気付いたことをメモしています.

この画面は、簡易表示です

2015 / 1月

VC 6 UNICODE C2664 , C2679 …

VC 6 コンソール AP で _UNICODE とした時,部分的に効いていない?様なエラー.

--------------------構成: T_RegKey - Win32 Release--------------------
コンパイル中...
T_RegKey.cpp
...\_s_func.hxx(71) : error C2664: 'wcscpy' : 1 番目の引数を 'char *' から 'unsigned short *' に変換できません。
...\_s_func.hxx(72) : error C2664: 'wcslen' : 1 番目の引数を 'const char *' から 'const unsigned short *' に...
...\StringFn.hxx(277) : error C2679: 二項演算子 '=' : 型 'unsigned short [3]' の右オペランドを扱う演算子は定義...
...\StrAryFn.hxx(118) : error C2665: 'wcspbrk' : 2 のオーバーロードは 1 番目の引数を 'char *' から要求の型に変換...
...
T_RegKey.obj - エラー 86、警告 0

先頭で #include <Afx.h> などとすればコンパイルは通る.
または,次の様に UNICODE を定義すれば良いみたい.
  #ifdef _UNICODE
    #ifndef UNICODE
    #define UNICODE
    #endif
  #endif
以前にも同じことを書いていた.


#include <Afx.h> などを追加した場合は,

--------------------構成: T_RegKey - Win32 Release--------------------
リンク中...
uafxcw.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__endthreadex" は未解決です
uafxcw.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__beginthreadex" は未解決です
c:\...\Release.060/T_RegKey.exe : fatal error LNK1120: 外部参照 2 が未解決です。
link.exe の実行エラー

T_RegKey.exe - エラー 3、警告 0

「プロジェクトの設定」-「一般」の「M..F..C..」で「共有 DLL で MFC を使用」などとする.


UNICODE の定義は,(VS12)\VC\AtlMFC\Include\AfxV_W32.h を参照して i_Define.hxx に追加した.
Windows.h より前に UNICODE が定義されてない場合は,i_Define.hxx をインクルードすれば良い.



  にほんブログ村 IT技術ブログへ

  • Categories:

コンソール 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 などを使うことは,やめ.



  にほんブログ村 IT技術ブログへ


コンテキストメニューが表示されない

あるダイアログベースの 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);
     …
     }


メニューが表示されない原因はリソース不足.
不要なエクスプローラのウィンドウを閉じて,意図した動作となることを確認.



  にほんブログ村 IT技術ブログへ


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 浮動小数点型からの変換



  にほんブログ村 IT技術ブログへ

  • Categories:

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) {
    ….
    }



  にほんブログ村 IT技術ブログへ


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 秒程度に.



  にほんブログ村 IT技術ブログへ



    top

    %d人のブロガーが「いいね」をつけました。