ANA国内線【PR】
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じゃ絶対に出来ないなぁ。


ソニーストア

# by isoq | 2012-01-31 01:06 | C/C++/Win32 | Trackback | Comments(0)
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 ・・・・・




ソニーストア

# by isoq | 2012-01-29 17:52 | C/C++/Win32 | Trackback | Comments(0)
MFCのCImageでPNGファイルのアルファブレンドがおかしいの解決方法
CImageで、PNGファイルを読み込むと、アルファブレンドがおかしい。

Photoshop、Office、Windows Paint(on Win7)では、正常に表示できる画像が、CImageで読み込むと、色が崩れたり、アルファ値がおかしかったりする。 Visual Studio 2010 IDE のリソースエディタ で読み込んでも、CImage と同じ画像が出てくるので、CImage自体に問題があり、Visual Studio 2010にもその問題が引き継がれているらしい。

これは、おそらくCImage のバグ。

なかなか原因がつかめなかったのですが、次のサイトで解決策を発見。

wrong alpha blending with CImage::AlphaBlend() & *.png

これを参考に、次のようにして問題が解決しました。


CImage m_image;
if(SUCCEEDED(m_image->Load(strFileName)))
{
    if(m_image->GetBPP() == 32)
    {
        // PNGのアルファ問題回避
        if(strFileName.Right(3).CompareNoCase(_T("png")) == 0)
        {
            unsigned char * pCol = 0;
            long w = m_image->GetWidth();
            long h = m_image->GetHeight();
            for(long y = 0; y < h; y ++)
            {
                for(long x = 0; x < w; x ++)
                {
                    pCol = (unsigned char *)m_image->GetPixelAddress(x,y);
                    unsigned char alpha = pCol[3];
                    if(alpha != 255)
                    {
                        pCol[0] = ((pCol[0] * alpha) + 128) >> 8;
                        pCol[1] = ((pCol[1] * alpha) + 128) >> 8;
                        pCol[2] = ((pCol[2] * alpha) + 128) >> 8;
                    }
                }
            }
        }

        // アルファチャンネルON
        m_image->SetHasAlphaChannel(true);
    }
}




ソニーストア

# by isoq | 2012-01-29 12:54 | C/C++/Win32 | Trackback | Comments(0)
MFCリボンのバグ。 サブウインドウのリボンでメニューを開くとメインウインドウが前面に表示される
Visual Studio 2010 / Visual C++ 2010 の MFC のリボンインターフェイスのバグ発見。
サブウインドウ上でRibbon ボタンによるメニュー表示の瞬間に、メインウインドウがアクティブになってしまう・・・

次のような場合に発生する。

① CMainFrame の代わりに、 CDialog などをメインウインドウにして、CMainFrame/View をサブウインドウにした場合。

② マルチトップレベルウインドウで、2つめ以降のCMainFrameを作成した場合

こんな時には、リボンがあるウインドウがメインウインドウではない状況が生まれるけど、このとき、サブウインドウでリボンのボタンのメニューを開こうとすると、メインウインドウがアクティブになって邪魔してくる。

原因を探ると、次の場所に行き着いた。


CMFCRibbonBaseElement* CMFCRibbonCategory::OnLButtonDown(CPoint point)
{
    CMFCRibbonBaseElement* pBtnScroll = HitTestScrollButtons(point);
    ...
    CMFCRibbonPanel* pPanel = GetPanelFromPoint(point);
    ...
    return pPanel->MouseButtonDown(point);



CMFCRibbonBaseElement* CMFCRibbonPanel::MouseButtonDown(CPoint point)
{
    if (m_pHighlighted != NULL)
    {
        ...
        m_pHighlighted->OnLButtonDown(point);



void CMFCRibbonButton::OnLButtonDown(CPoint point)
{
    ...
    OnShowPopupMenu();



void CMFCRibbonButton::OnShowPopupMenu()
{
    ASSERT_VALID(this);
    if (IsDroppedDown())
    {
        // if the button already has a menu, don't create another one!
        return;
    }
    CWnd* pWndParent = GetParentWnd();
    if (pWndParent->GetSafeHwnd() == NULL)
    {
        ASSERT(FALSE);
        return;
    }
    CMFCRibbonBar* pTopLevelRibbon = GetTopLevelRibbonBar();
    if (pTopLevelRibbon->GetSafeHwnd() == NULL)
    {
        ASSERT(FALSE);
        return;
    }
    CMFCRibbonBaseElement::OnShowPopupMenu();
    const BOOL bIsRTL = (pTopLevelRibbon->GetExStyle() & WS_EX_LAYOUTRTL);
    CWnd* pWndOwner = pTopLevelRibbon->GetSafeOwner();



CWnd* PASCAL CWnd::GetSafeOwner(CWnd* pParent, HWND* pWndTop)
{
    HWND hWnd = GetSafeOwner_(pParent->GetSafeHwnd(), pWndTop);
    return CWnd::FromHandle(hWnd);



HWND PASCAL CWnd::GetSafeOwner_(HWND hParent, HWND* pWndTop)
{
    // get window to start with
    HWND hWnd = hParent;
    if (hWnd == NULL)
    {
        CFrameWnd* pFrame = CCmdTarget::GetRoutingFrame_();        // ここがNULLになる!
        if (pFrame != NULL)
            hWnd = pFrame->GetSafeHwnd();
        else
            hWnd = AfxGetMainWnd()->GetSafeHwnd();    // だから、ここで メインウインドウが返っちゃう!
                    // → メインウインドウがポップアップメニューのオーナーになる
                    //     → メインウインドウがアクティブになっちゃう
    }



CFrameWnd* PASCAL CCmdTarget::GetRoutingFrame_()
{
    CFrameWnd* pFrame = AfxGetThreadState()->m_pRoutingFrame;    // これがNULLになっている!
    return pFrame;
}



CMFCRibbonButton::OnShowPopupMenu() をオーバーライドして、GetSafeOwner() を使わないように改造するのが一番簡単だけど、Visual C++ 2010 の リソースエディタでリボンを作成して、自動読み込みを行うと、どうもカスタムのCMFCRibbonButton派生クラスを差し込むことは難しいみたい。MFCのソースとにらめっこしたけど、どうやら不可能。こんな時は、ライブラリ内の特定クラスを無効化して、自分で再定義したクラスをはめ込みたいけど出来ないよね・・・。

だから、AfxGetThreadState()->m_pRoutingFrame に CMainFrame* を突っ込めば良いんじゃね??

って事で、次のようにしてみました。


BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
    AfxGetThreadState()->m_pRoutingFrame = this;
    return CFrameWndEx::PreTranslateMessage(pMsg);
}

CMainFrame::~CMainFrame()
{
    AfxGetThreadState()->m_pRoutingFrame = 0;
}



PreTranslateMessage で、CMainFrame にメッセージが飛んできたら常に AfxGetThreadState()->m_pRoutingFrame にポインタをセットします。

こうすることで、(正しい処置かどうかは不明ですが・・・)現在アクティブな CMainFrame 上にメニューを表示することが出来ました!

CMainFrame の消滅時に AfxGetThreadState()->m_pRoutingFrame をクリアしないと、終了時にエラーが出ました。


ソニーストア

# by isoq | 2012-01-29 12:41 | C/C++/Win32 | Trackback | Comments(0)
GUI プログラムでコンソールを使用する(標準出力) -簡易版-
GUI プログラムでコンソールを使用する(標準出力) を簡単にすると、こんな感じ。


AllocConsole();
freopen 括弧はじめ "CON", "w", stdout); // 標準出力の割り当て
_tsetlocale(LC_ALL, _T("Japanese"));


setlocale() を行わないと、Unicode 環境で Unicode をコンソールに出力したときに、
ASCII以外の文字が表示されない・・・
つまり、日本語、漢字が表示できない。

つまらないところで、つまずいてしまい、調べるのに時間が掛かってしまった。。。


ソニーストア

# by isoq | 2011-12-09 15:20 | C/C++/Win32 | Trackback | Comments(0)
Windows x64 環境向けアプリが 0xc000007b エラーで起動しない

原因は、いろいろあるかと思いますが、私の場合は、一部のDLLが32ビット版でした。

すべて64ビット版であることを再確認して、実行したところ、正しく動きました。

サードパーティ製のDLLなど、32ビットか64ビットか、わかりにくいことがありますね。

それではまりました。

aaa.dll と aaa.x64 というファイルがあって、 aaa.x64 を aaa.dll に改名して使ってみたところ、動きました。

どちらも、 x64 フォルダに入っていたんだけど、、、
ドキュメントに書いてあったか???


ソニーストア

# by isoq | 2011-12-07 20:11 | C/C++/Win32 | Trackback | Comments(0)
バイオ届きました!
昨日、新しいパソコンが届きました。

SONY VAIO C です!

まっピンクです!
        ↓
最新の Intel Core i5 です!
        ↓
ノートPCなのに、15.5インチ フルHD液晶!(1920x1080)です。
        ↓
高性能グラフィック(AMD Radeon HD 6630M)も付いてて、ゲームもピグもライフもばっちり!

        ↓


        ↓


        ↓
この構成とデザインなのに、国内メーカー製ではあり得ないくらい、かなりのお手頃価格でした!
SONYオフィシャルのオンラインストア ソニーストア で購入しました。

本当は、もっと安いノートPCをビックカメラに見に行ったんですが、いろいろ見て、このVAIOを見つけて、購入しようとしたら、ビックの人もビックのPCでオンラインで購入の代理するだけ(あと、オンラインでカード使いたくない人は・・・なんていってましたが。)で、家で買っても同じとの事だったから、家に帰ってから、ソニーストアで、じっくり構成を選んでから購入しました。

色からもわかると思いますが、かみさん専用です (^_^)

最初からたくさんのソフトが入っているから、要らないソフト(ほとんどwww全部いらないじゃん)を、アンインストールする所から始まりました。こういうところが、国内メーカー製PCを買ったなぁwww!という充実感が得られる所ですよね? (^_^;)

あ、筆ぐるめ が入ってましたよ!
今年は、これで年賀状します!


        ↑
メモリだけは、2GBの最小構成で購入したので、起動にやや時間がかかります。
そのためか、かみさんがやや不満げです。

そこで、別に格安メモリを手配済みです。

明日か、明後日には、8GB搭載になります♪





ソニーストア

# by isoq | 2011-11-29 00:30 | コンピュータ | Trackback | Comments(0)
ママ専用PC購入! SonyのノートがフルHD+Core i5+Radeonで 6万円台!国内メーカーで一番のコスパ。
↓ これ買いました! 国内メーカー製ノートパソコンで、一番のコスパと思う。

↓ しかも、ピンク! 超お気に入りみたいです。
↓ (そこだけは外せないらしい・・・)


ソニーストア

追記:

BTOで、

15.5インチのフルHD液晶に変えて、

Core i3 -> Core i5 に変えて、

AMD Radeon HD 付きで、

6万円台中盤で買えました!

3年保証もついているので、安心だし。

今回は、安くあげるために、

メモリ 2GB
HDD 320GB
光学ドライブ DVD±RW
オフィス なし

に押さえました。

メモリは、上海問屋で 8GB(DDR3-1333 SODIMM 4GBx2)が 3,000円だし、

HDDは、足りなくなったら、USB3.0の外付けつければいいし、

ブルーレイも外付けが安くなってからでいいし、

オフィスは、別に買ってあるし、無くても Open Office でも事足りるし。


フルHD液晶が選べるだけでもすごい事だけど、

フルHD液晶を選んで、6万円台なんて、台湾メーカーもびっくりの価格帯です!

久しぶりに、いい買い物ができました。




ソニーストア

# by isoq | 2011-11-15 21:21 | コンピュータ | Trackback | Comments(0)
ATOK for Android 試用しています!
スマホに日本一の日本語変換ソフト ATOK を入れました!



とりあえず、Android マーケットから14日間体験版を入れたのですが、

独自のフラワータッチという入力方式がすばらしい!



ATOKサイトのデモビデオ↓参照のこと。




www.justsystems.com
慣れた入力操作のまま思い通りに。流れるような入力の心地よさをあなたに。ATOK for Android



↑ものすごい速さで文章を打ち込むサクラのおにいさん。。。



こんな早く打てるわけないだろ!



って思っていたんだけど、フラワータッチを実際に使ってみると、慣れればあれに近い速度で入力できそう!



フラワータッチだけじゃなくて、いろいろな操作方法でタップ数を極限まで減らし、なおかつわかりやすくまとまっていて、使いやすいです。



すばらしいすぎるUIだ!



しかも、ソニエリ EXPERIA に標準搭載のPO Boxタッチと比べものにならないくらい軽い。

今まで、メール画面出しても入力できるようになるまでの微妙な待ち時間がうっとうしかったんだけど、それがなくなりました。




おすすめです。



ソニーストア

# by isoq | 2011-11-11 02:42 | モバイル | Trackback | Comments(0)
メモリ安くなったねーー!
私は、上海問屋のこちら↓にあるメモリのリストから、
http://item.rakuten.co.jp/donya/c/0000000179/

A-DATA DDR3 PC3-12800 4GB×2本(計8GB) ¥3,619 を買いました!

このメモリ、ヒートシンクがついている結構良さげなメモリです。
見た感じ、かっこいいです。
(PCに搭載したら見えないんですけどね ^^;)

しかも、8GBで 3,619円ですよ! 安すぎwww

ほんと、安くなった。

今後、メモリの値上がりが見込まれているそうなので、

買うなら今かもしれません。


自宅のPCは、これで4GB+8GB=12GBになりました!

このメモリを生かして、

Windows 7 + XP Mode + Ubuntu で、マルチOS三昧な

環境になってます。



ソニーストア

# by isoq | 2011-10-29 01:56 | コンピュータ | Trackback | Comments(0)
VMWare で Ubuntu 11.10 日本語 Remix をやってみました
最近のLinuxは、本当に使い安くなった!

Ubuntu 11.10 日本語 Remix を VMWareにインストールして使って見ました。

VMWare Player 4 で仮想マシンを作ってインストールしたんだけど、

iso ファイルから直接簡易インストールを行ったところ、なぜかコマンドライン起動になってしまい、startx しないと、Xウインドウシステムが起動しない状態。
最初からX起動する方法を調べるのが面倒だったので、別の仮想マシン作って、通常インストールしました。

通常インストールすると、VMWare Toolsを手動でインストールしないといけないんだね。

管理者権限のとり方が変わっていて、su じゃなくて、 sudo を使って、なんとか VMWare Tools のインストールに成功! ウインドウのサイズに合わせて画面の大きさが変わるようになったし、3Dアクセラレーションも効いているみたいだし、メモリ2GBと、2コアを Ubuntu on VMWare に割り当てたため、かなり快適に動きます。

IMEのキーバインドもf10キー以外は、Windows標準のMSーIMEと一緒みたいだし。
使いやすいです。(うそです。キーバインドをATOK風に変えれないの???)

変換精度も、MSーIMEとどっこいどっこいだけどね。

あとは、何とかして、ATOKを入れたいなぁwww

しばらく、この環境で使ってみようか十もいます。

ちなみに、今も Ubuntu で書いてます。

Firefoxは、いつも使っているAddonがすべて使える!

Windowsとほとんど同じ使い勝手。

これは、もうWindowsいらない勢い。

ソニーストア

# by isoq | 2011-10-29 01:45 | コンピュータ | Trackback | Comments(0)
Android用のエキブロ投稿アプリが出たようですね
投稿画面のお知らせで気づきました。

Android携帯専用のブログ投稿アプリ(無料)をリリースしました

なかなか良さげではないですか。

投稿時にドラッグアンドドロップで画像をアップできるようになったのも便利で感動したけど、

スマホからお手軽に写真が入ったブログが編集・投稿できるらしい。

しかも、画像アップロードのとき、画像のサイズが指定できるらしい!

これ、他にはない便利機能かも。

まだ使ってみてはないんだけど、

写真がカメラ撮影から直にブログに貼れたら、

エキブロの更新頻度が上がりそう!

最近は、ほとんどフェイスブックなので・・・

何個もブログ持ってて、

どこかしこにバラバラ投稿するから、

もう、どのブログがメインなのかわからないっすw

ソニーストア

# by isoq | 2011-10-27 23:47 | 日記 | Trackback | Comments(0)
Visual Studio 2010
いままで、敬遠していた Visual Studio 2010 ですが、

使い始めてみると、今までのVSに戻れなくなりそうなほど、

かなり便利です・・・

やばすw

SP1が出て、

動作もきびきびし始めたみたいだし。

これは・・・

はまりそう。
ソニーストア

# by isoq | 2011-10-27 23:40 | 開発日記 | Trackback | Comments(0)
Visual Studio 2010 の Ctrl+クリック で定義表示を無効化
Microsoft Visual Studio 2010 では、エディタ上で Ctrl+クリック を行うと、「単語選択」ではなく、「その単語の定義へ移動」というコマンドになってしまうため、非常に不便でした。

この設定は、「ツール → オプション」 メニューの設定から、変更可能です。

追記(10/27):
これは、Productivity Power Tools という機能拡張の機能らしいです。
ツール→機能拡張マネージャ からインストールできます。(追記ここまで)



あと、現在行のハイライトもうざいのでOFF。
(Highlight Current Line を OFF)

これで少しは使いやすく&見やすくなります。

あと、起動が遅い事と、動作が鈍い事が解決出来たら、すばらしい開発環境になりそうです。




ソニーストア

# by isoq | 2011-09-16 11:50 | C/C++/Win32 | Trackback | Comments(0)
スマホ買いました
スマホからの投稿です。



やっと人並みにスマホを持ちましたwww

エキサイトはブログの表示はスマホ対応だけど、

投稿画面はPC版なんだね...

入力画面が、画面に収まりませんが...(((^_^;)

でも、PCでできることは、一通りできるみたい!



画像の投稿とかもね♪

スマホは、ソニエリのauのXPERIA acroです。

スルスル動いて快適です。

これで、ハードキーボードが付いたら完璧ですが、

ソフトキーボードです。

慣れれば、なかなか快適ですが、

いかんせんタイプミスが多いです。

それに、人差し指一本で打つので遅いです。

他の指は、接触面の予測が難しく使えません!

ハードキーボードなら少なくとも2本指で打てるのにぃwww

ソニーストア

# by isoq | 2011-09-13 21:09 | モバイル | Trackback | Comments(0)
< 前のページ 次のページ >