タグ:C++ ( 12 ) タグの人気記事

e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

MFCをまねしたちょこっとした便利マクロ

MFCをまねしたちょこっとした便利マクロ


#include <tchar.h>
#define TRACE(str, ...) \
{ \
    TCHAR c[256]; \
    _stprintf( c, str, __VA_ARGS__ ); \
    OutputDebugString( c ); \
}

[PR]
by isoq | 2013-10-22 16:03 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

CTabView/CMFCTabCtrl のタブをマウスホイールでスクロールさせる

Firefox で Tab Mix Plus とかの設定調整アドオンを使用すると、タブ上にマウスポインタを置き、ホイールをスクロールすると、次々とタブを切り替える事が出来る機能を有効にすることが出来ます。これって結構便利です。

で、MFCのCTabViewを使ってみたところ、タブが収まりきらなくなると画面外にタブが並び、それを画面内に持ってくるにはボタンで、タブを1つずつ移動していかないといけない。これがとても面倒で、タブがたくさんあるとうっとうしい。ボタンが小さくて、右の方にあるから余計に使いにくい。

そこで、マウススクロールでタブを切り替えできないかと、それらしき機能を探したが見つからない。

CTabView で使用しているタブコントロールは、 CMFCTabCtrl です。

一番簡単なのは、CMFCBaseTabCtrl::GetActiveTab() で現在アクティブなタブのインデックスを取得して、CMFCBaseTab::SetActiveTab() を使って、+1 や -1 したインデックスのタブをアクティブにして、EnsureVisible() で画面に表示する方法。

でも、今回は、タブをアクティブにしないでスクロールだけしたかった。
というのも、たくさんタブがあって、その1つ1つがアクティブになった時に画像データを読み込むんだけど、画像データのサイズが半端なくでかい。
最小100MB~最大1GB強の画像データ・・・ってどんなんだ!

A4一枚程度を 1200dpi / 48bit カラーでスキャンした生データなのです。

だから、なるべく使ってない画像は開きたくない。

そこで、次のように、ちょっと危険な手を使って、スクロールを実現してみました。

// CMFCTabCtrl のハッククラス(ポインタをキャストして使用する)
class CMFCTabCtrlEx : public CMFCTabCtrl
{
public:
    int GetTabsHorzOffset(){ return m_nTabsHorzOffset; }    // オフセット取得
    void SetTabsHorzOffset(int nOffset)                     // オフセットをセット
    { 
        m_nTabsHorzOffset = nOffset;
        AdjustTabs();
        AdjustTabsScroll();
        RedrawWindow();
    }
    int GetTabsHorzOffsetMax(){ return m_nTabsHorzOffsetMax; } // オフセットの最大値を取得
private:
    CMFCTabCtrlEx();    // インスタンス化拒否
};
 
BOOL CXxxTabView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    CMFCTabCtrlEx* pTabCtrlEx = (CMFCTabCtrlEx*)&GetTabControl();
    pTabCtrlEx->ScreenToClient(&pt);
    if(pTabCtrlEx->IsPtInTabArea(pt))
    {
        int nPos = pTabCtrlEx->GetTabsHorzOffset();
        int nMax = pTabCtrlEx->GetTabsHorzOffsetMax();
        int nScroll = 50;    // スクロール量(ピクセル?)
        if(zDelta < 0)
        {
            int nTarget = nPos + nScroll;
            if(nTarget > nMax) nTarget = nMax;
            if(nTarget < 0) nTarget = 0;
            pTabCtrlEx->SetTabsHorzOffset(nTarget);
        }
        else
        {
            int nTarget = nPos - nScroll;
            if(nTarget < 0) nTarget = 0;
            pTabCtrlEx->SetTabsHorzOffset(nTarget);
        }
    }
    else
    {
        return CTabView::OnMouseWheel(nFlags, zDelta, pt);
    }
}



CMFCTabCtrlのソースコードを眺めて、スクロール処理している部分を特定して、擬似的にそれを実行する。
変数が、protected だったから、CMFCTabCtrl のままだとアクセスできないから、ダミーの派生クラスCMFCTabCtrlExを作成して、そのポインタに無理矢理CMFCTabCtrlのアドレスを突っ込んで、独自処理を組み込んだ見せかけの派生クラス上で処理させました。

こんな事が出来るのも、C++だからこそ。
.NETじゃ絶対に出来ないなぁ。
[PR]
by isoq | 2012-01-31 01:06 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

MFC なぜかメッセージボックスが表示できなくなる原因が判明

ここのところ、作成したMFCプログラムでなぜか、どこに次のようなコードを書いてもメッセージボックスが表示できなくなってしまっていました。


MessageBox(_T("test"), _T("test"), MB_OK);


とか


AfxMessageBox(_T("test"));


とかです。

本当に基本的なメッセージボックスの表示方法ですが、どこに書いても音が鳴るだけで、メッセージボックスが表示されない!

そして、音の後に [Alt] キーを押すと、なぜかメッセージボックスが表示される・・・

メッセージボックスの表示が [Alt] キー入力を待っているような感じになってしまっていたのです。

原因がわからず、プログラム全体を 少しずつコメントしたり戻したりした結果、努力の甲斐無く、全く原因がつかめませんでした。

そして、スケルトンからやり直して、ちょっとづつコードを足していって・・・最初は問題なく、表示されていたため、ちょっとがんばってたくさんコードを移植すると発生! (^^;) もっとじっくりやればよかった・・・

それでもその間のコードを確認しながらやってみるてやっと鍵を見つけました!

ここです!


void CXxxxYyyyView::OnPaint()
{
    CPaintDC dc(this);    // これを消していました



CPaintDC は、画面の無効領域だけを更新するためのDCですが、使わなかったので、消してしまって、CDC* pDC = GetDC(); とやって、そちらのDCを使用していました。

が、どうやらここで、CPaintDC をインスタンス化しないことが原因で、メッセージボックスが出なくなっていたようです。

こんな事もあるんですね・・・・ MFC ・・・・・
[PR]
by isoq | 2012-01-29 17:52 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

OpenGLでビットマップ画像データを背景に描画

以前、DirectShowでキャプチャしたカメラ画像を
OpenGLの背景に差し込んだ時の、テストコードの一端。
めも。

void DrawVideo(DShowCapture* vcap)
{
if(vcap)
{
// メモリ確保は起動時1回だけ
// シンクロが必要かも
static long nDataSize = 640 * 480 * 3; //vcap->GetBufferSize();
static long* pbData = (long*)new BYTE[nDataSize];
static BITMAPINFO bmi;
if(vcap->CopyFrameData(pbData, nDataSize, &bmi))
{
// glDrawPixels をコールするときには、PROJECTIONマトリックスを
// 初期化しないと画面に表示されない。(普通の画面の場合)
// その後、DEPTHバッファをクリアすれば、画像を背景に
// OpenGLでレンダリングが出来る
GLint oldMatrixMode;
glGetIntegerv(GL_MATRIX_MODE, &oldMatrixMode);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glPixelZoom(1,1);
glRasterPos2i(-1 , -1);
glDrawPixels(640 , 480 , GL_BGR_EXT , GL_UNSIGNED_BYTE , pbData);
glPopMatrix();
glMatrixMode(oldMatrixMode);
glClear(GL_DEPTH_BUFFER_BIT);
}
else
{
//MessageBox(0, "can't get image", "fakegl", MB_OK);
}

//delete [] pbData;
}

}

[PR]
by isoq | 2011-03-03 11:35 | 3Dグラフィックス
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

サンプル:アクセッサー オペレータ

class Test
{
public:

Test()
{
for(int i=0; i<100; i++)
{
value[i] = i;
}
}

int operator[](int idx){ return value[idx]; }

int value[100];
};


int _tmain(int argc, _TCHAR* argv[])
{
Test t;

printf("%d\n", t[10]);

return 0;
}

[PR]
by isoq | 2011-01-18 11:35 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

サンプル:テンプレートメンバ関数


class Test
{
public:
Test()
{
for(int i=0; i<100; i++)
{
iValue[i] = i;
dValue[i] = 1.0 / double(i);
}
}

void Evaluate()
{
//printf("%d, %f\n", GetAt(iValue, 10), GetAt(dValue, 10)); // <>は省略可
printf("%d, %f\n", GetAt(iValue, 10), GetAt(dValue, 10));
}

template
T GetAt(T* array_ptr, int index)
{
return array_ptr[index];
}


int iValue[100];
double dValue[100];
};

int _tmain(int argc, _TCHAR* argv[])
{
Test t;
t.Evaluate();
return 0;
}

[PR]
by isoq | 2011-01-18 11:33 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

ImageJ の Analyze 形式のヘッダーファイルの解析 更新


enum ImageType
{
IM_P_8 = 0x0000,
IM_G_8 = 0x0002,
IM_G_16 = 0x0004,
IM_G_32 = 0x0010,
IM_RGB_24 = 0x0080
};


struct AnalyzeHDR
{
//0x00000000
unsigned char head[4];// 00 00 01 5C
char desc[12];// 長さが不明なので、unknown10 まで伸る可能性あり

//0x00000010
unsigned char unknown10[16];

//0x00000020
unsigned char unknown20[10];
unsigned short x;// xピクセル数
unsigned short y;// yピクセル数
unsigned short z;// zピクセル数

//0x00000030
unsigned char unknown30[8];
char unit[8];

//0x00000040
unsigned char unknown40_1[6];
unsigned short type;// 画像のタイプ
unsigned short depth;// ビット数
unsigned char unknown40_2[6];

//0x00000050
float px;// xピクセルサイズ
float py;// yピクセルサイズ
float pz;// zピクセルサイズ
unsigned char unknown50[4];

//0x00000060
unsigned char unknown60[16];

//0x00000070
unsigned char unknown70[16];

//0x00000080
unsigned char unknown80[16];

//0x00000090
unsigned char unknown90[16];

//0x000000A0
unsigned char unknownA0[16];

//0x000000B0
unsigned char unknownB0[16];

//0x000000C0
unsigned char unknownC0[16];

//0x000000D0
unsigned char unknownD0[16];

//0x000000E0
unsigned char unknownE0[16];

//0x000000F0
unsigned char unknownF0[16];

//0x00000100
unsigned char unknown100[16];

//0x00000110
unsigned char unknown110[16];

//0x00000120
unsigned char unknown120[16];

//0x00000130
unsigned char unknown130[16];

//0x00000140
unsigned char unknown140[16];

//0x00000150
unsigned char unknown150[12];
};


ImageJ の Analyze 形式ファイルを扱う事になったんだけど、
ヘッダーの情報が見つからなかったので、解析してみた。

不明なデータがたくさんだけど、なんとか必要な部分だけは取り出せた。
[PR]
by isoq | 2010-07-08 19:19 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

エンディアンを変換するためのコード

#include
void ReverseBytes(void *start, int size)
{
char *begin = (char*)start;
char *end = begin + size;
std::reverse(begin, end);
}
#define SwapEndian(a) ReverseBytes(&a, sizeof(a));


Big Endian -> Little Endian
Little Endian -> Big Endian

両方とも、いけます!
というか、データの並び方が違うだけだから、解釈の違いでしか無いから、
当たり前と言えば当たり前。
[PR]
by isoq | 2010-07-08 19:17 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

便利なPath系Win32API関数

パスの連結など、便利に利用できる Path*** 関数が Win32API に用意されています。
この関数の名前 Path*** というのを、すぐに忘れてしまうので、メモ。
(主に、自分のブログを検索した時に引っかかるように。)


Shell Path Handling Functions

--------------------------------------------------------------------------------
This section describes the Microsoft Windows Shell path handling functions. The programming elements explained in this documentation are exported by Shlwapi.dll and defined in Shlwapi.h and Shlwapi.lib.


PathAddBackslash
Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing backslash, no backslash will be added.
パスの最後に、\ 記号を追加。

PathAddExtension
Adds a file extension to a path string.
パスの最後に、拡張子を追加。

PathAppend
Appends one path to the end of another.
他のパスの後ろに、パスを追加。
例: c:\test1\test2 + test3 = c:\test1\test2\test3
相対パス非対応

PathBuildRoot
Creates a root path from a given drive number.

PathCanonicalize
Canonicalizes a path.

PathCombine
Concatenates two strings that represent properly formed paths into one path; also concatenates any relative path pieces.
フォルダ名とファイル名を連結。

PathCommonPrefix
Compares two paths to determine if they share a common prefix. A prefix is one of these types: "C:\\", ".", "..", "..\\".

PathCompactPath
Truncates a file path to fit within a given pixel width by replacing path components with ellipses.

PathCompactPathEx
Truncates a path to fit within a certain number of characters by replacing path components with ellipses.

PathCreateFromUrl
Converts a file URL to a Microsoft MS-DOS path.

PathCreateFromUrlAlloc
Creates a path from a file URL.

PathFileExists
Determines whether a path to a file system object such as a file or directory is valid.

PathFindExtension
Searches a path for an extension.

PathFindFileName
Searches a path for a file name.

PathFindNextComponent
Parses a path for the next path component.

PathFindOnPath
Searches for a file.

PathFindSuffixArray
Determines whether a given file name has one of a list of suffixes.

PathGetArgs
Finds the command line arguments within a given path.

PathGetCharType
Determines the type of character in relation to a path.

PathGetDriveNumber
Searches a path for a drive letter within the range of 'A' to 'Z' and returns the corresponding drive number.

PathIsContentType
Determines if a file's registered content type matches the specified content type. This function obtains the content type for the specified file type and compares that string with the pszContentType. The comparison is not case-sensitive.

PathIsDirectory
Verifies that a path is a valid directory.

PathIsDirectoryEmpty
Determines whether a specified path is an empty directory.

PathIsFileSpec
Searches a path for any path-delimiting characters (for example, ':' or '\' ). If there are no path-delimiting characters present, the path is considered to be a File Spec path.

PathIsHTMLFile
Determines if a file is an HTML file. The determination is made based on the content type that is registered for the file's extension.

PathIsLFNFileSpec
Determines whether a file name is in long format.

PathIsNetworkPath
Determines whether a path string represents a network resource.

PathIsPrefix
Searches a path to determine if it contains a valid prefix of the type passed by pszPrefix. A prefix is one of these types: "C:\\", ".", "..", "..\\".

PathIsRelative
Searches a path and determines if it is relative.

PathIsRoot
Parses a path to determine if it is a directory root.

PathIsSameRoot
Compares two paths to determine if they have a common root component.

PathIsSystemFolder
Determines if an existing folder contains the attributes that make it a system folder. Alternately, this function indicates if certain attributes qualify a folder to be a system folder.

PathIsUNC
Determines if the string is a valid Universal Naming Convention (UNC) for a server and share path.

PathIsUNCServer
Determines if a string is a valid UNC for a server path only.

PathIsUNCServerShare
Determines if a string is a valid UNC share path, \\ server\ share.

PathIsURL
Tests a given string to determine if it conforms to a valid URL format.

PathMakePretty
Converts a path to all lowercase characters to give the path a consistent appearance.

PathMakeSystemFolder
Gives an existing folder the proper attributes to become a system folder.

PathMatchSpec
Searches a string using a MS-DOS wild card match type.

PathMatchSpecEx
Searches a string using a MS-DOS wild card match type and a flag.

PathParseIconLocation
Parses a file location string containing a file location and icon index, and returns separate values.

PathQuoteSpaces
Searches a path for spaces. If spaces are found, the entire path is enclosed in quotation marks.

PathRelativePathTo
Creates a relative path from one file or folder to another.

PathRemoveArgs
Removes any arguments from a given path.

PathRemoveBackslash
Removes the trailing backslash from a given path.

PathRemoveBlanks
Removes all leading and trailing spaces from a string.

PathRemoveExtension
Removes the file extension from a path, if one is present.

PathRemoveFileSpec
Removes the trailing file name and backslash from a path, if they are present.

PathRenameExtension
Replaces the extension of a file name with a new extension. If the file name does not contain an extension, the extension will be attached to the end of the string.

PathSearchAndQualify
Determines if a given path is correctly formatted and fully qualified.

PathSetDlgItemPath
Sets the text of a child control in a window or dialog box, using PathCompactPath to ensure the path fits in the control.

PathSkipRoot
Parses a path, ignoring the drive letter or UNC server/share path parts.

PathStripPath
Removes the path portion of a fully qualified path and file.

PathStripToRoot
Removes all parts of the path except for the root information.

PathUndecorate
Removes the decoration from a path string.

PathUnExpandEnvStrings
Rreplaces several folder names in a fully qualified path with their associated environment string.

PathUnmakeSystemFolder
Removes the attributes from a folder that make it a system folder. This folder must actually exist in the file system.

PathUnquoteSpaces
Removes quotes from the beginning and end of a path.

SHSkipJunction
Checks a bind context to see if it is safe to bind to a particular component object.

UrlApplyScheme
Determines a scheme for a specified URL string, and returns a string with an appropriate prefix.

UrlCanonicalize
Converts a URL string into canonical form.

UrlCombine
When provided with a relative URL and its base, returns a URL in canonical form.

UrlCompare
Makes a case-sensitive comparison of two URL strings.

UrlCreateFromPath
Converts a MS-DOS path to a canonicalized URL.

UrlEscape
Converts characters in a URL that might be altered during transport across the Internet ("unsafe" characters) into their corresponding escape sequences.

UrlEscapeSpaces
A macro that converts space characters into their corresponding escape sequence.

UrlFixupW
Attempts to correct a URL whose protocol identifier is incorrect. For example, htttp will be changed to http. Priority is given to the first character in the protocol identifier section so htp will be converted to http instead of ftp.

UrlGetLocation
Retrieves the location from a URL.

UrlGetPart
Accepts a URL string and returns a specified part of that URL.

UrlHash
Hashes a URL string.

UrlIs
Tests whether or not a URL is a specified type.

UrlIsFileUrl
Tests a URL to determine if it is a file URL.

UrlIsNoHistory
Returns whether a URL is a No History URL.

UrlIsOpaque
Returns whether a URL is opaque.

UrlUnescape
Converts escape sequences back into ordinary characters.

UrlUnescapeInPlace
Converts escape sequences back into ordinary characters and overwrites the original string.
[PR]
by isoq | 2010-07-05 14:03 | 開発日記
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇

list iterator not dereferencable の理由



std::list を使用していて、list iterator not dereferencable という意味不明のエラーが出た。
ランタイムのアサーション フェイリヤー(Assertion Failure) で、デバッグも不可能。。。

いろいろ考えてコードを直してみても、いっこうに修正ができる気配がない。

結局、原因は、次のコードだった。

std::list::iterator it2 = objList.end();
Obj* obj = *it2;
it2--;


end() で取得したイタレータは、データ要素を指していないで、
最後のデータ要素の1つ後ろを指している!

ということを忘れていました。。。

書いている途中は覚えていたんだけど、
書き終わった頃にはすっかり。。。

簡単な原因でも、エラーの意味が不明だと、解決に時間がかかる。。。
慣れだけど。
[PR]
by isoq | 2010-03-02 11:56 | C/C++/Win32
e87.com(千趣会イイハナ) 花を贈るなら日比谷花壇