C++

2018年03月21日

vs2017のリソースファイルバグ

Visual Studio 2017 にてリソースファイルを使ったプロジェクトでビルドエラーが発生しました。

症状

リンクと似たような状況になりました。

原因となっている個所を見てみると確かにおかしいです。


resource

リンクではLANGUAGE が言語と置き換わっているようですが、私のところでは読点がまだ変換されてしまっているようです。中途半端にバグが直っているのは嫌ですね。 これはどうしようもないので、直接読点をカンマに修正すればビルドはうまくいくようになります。

バージョン


version

Version 15.6.3 ではまだ直っていないのでちゃんとフォローしてあげましょう。 ちなみにこの記事を書いた時点での最新版なので、お気をつけてください。

※2018/05/06追記
Version 15.6.7 でもまだ直っていません



rabbitcats at 21:48|PermalinkComments(0)

2017年05月27日

vs2017でのboost ビルド時エラー

vs2017 でboost1.64.0 をビルドしようとしたときに所々でエラーが出たのでその時のメモです。

環境

ツールまわり

  • visual studio 2017
  • Windows Kits 10.0.15063.0

実行環境

x86 Native Tools Command Prompt for VS 2017 を管理者権限にて実行

bootstrap.bat から呼び出される %boost_root%/tools/build/src/engine/build.bat には次のように書いてありました。

If you have Visual Studio 2017 installed you will need to build from
the Visual Studio Command Prompt for VS 2017 as we where unable to
detect your toolset installtion.

エラー

ことの始まりはbootstrap.bat を動かしたときの次のエラーでした。

execnt.c(57): fatal error C1083: include ファイルを開けません。'tlhelp32.h':No such file or directory

ということで、b2.exe とかbjam.exe が作られませんでした。

tlhelp32.h

tlhelp32.h 自体のことについては置いておいて、見つからないと言われるので適当なプロジェクトでインクルードしてみると、

C:\Program Files (x86)\Windows Kits\8.1\Include\um\TlHelp32.h

にあるとのこと。あるじゃん…
それはそうと、Prompt 上のインクルードパスを調べたところ、Windows Kits は8.1 ではなく10系列が設定されていました。

C:\Program Files (x86)\Windows Kits\10\include\10.0.15063.0\...

上記ディレクトリ以下でtlhelp32.h があるか確認したところ、ありませんでした。それじゃあ見つからないと言われるのも仕方がないですね。

visual studio 2017 を最初に入れた時にWindows Kits は10.0.14393.0 が入っていたのでそちらを確認するとファイルはあったのでどうにか14393を使うようにしたところb2.exe とかbjam.exe が作られました。

エラーは続くよ

そのあとboost をビルドしようとすると、winsock2 のインクルードでやっぱりWindows Kits は10.0.15063.0 のディレクトリを参照しようとしました...

オチ

さいごに、初心に戻ってインストーラをまた立ち上げてみたところデスクトップC++x86およびx64用 Windows 10 SDK (10.0.15063.0) がチェックついてませんでした…
チェックつけてやり直したらうまくいったので、もし同じ困り方をしたらこのコンポーネントがちゃんと入っているかチェックしてみてください。

全部ちゃんとインストールしてたと思ったのに哀しかったです...



rabbitcats at 12:01|PermalinkComments(0)

2017年05月18日

locale でのDEBUG_NEW によるコンパイルエラー

std::locale を使ってifstream でUTF-8 文字コードのファイルを読み込む設定をした際にコンパイルエラーに遭遇したので、覚書として書きます。

コンパイラ

VC10 (Visual Studio 2010 Professional sp1)

起こったこと

次のコードをコンパイルしたときに、環境を変えるとコンパイルが通ったり通らなかったりしました。

コード

#include <codecvt>
#include <fstream>

...

std::wifstream ifs;
ifs.imbue(std::locale(std::locale::empty(), new sd::codecvt_utf8<wchar_t>));

エラー

UTF-8 locale in Visual C++ 2010 にあるのと同じエラーが出たので引用します。

error C2661: 'std::locale::facet::operator new' : no overloaded function takes 3 arguments
error C2664: 'std::locale::locale(const char *,std::locale::category)' : cannot convert parameter 1 from 'std::locale' to 'const char *'

回避方法

リンク先にあるようにdebug 時にDEBUG_NEW を使わせないように下記のようにコードを変更すれば回避はできました。

ifs.imbue(std::locale(std::locale::empty(), ::new sd::codecvt_utf8<wchar_t>));

new をグローバルスコープを付けてDEBUG_NEW を使わせないように変更。
ただし、回避はできても根本的な解決には至っていないのでどうにか原因を突き止めたいです。

ちなみに自分の使っている計算機はハードディスク周りが不調なのでそっちが原因なのかなとも思いましたが、VS2010 をクリーンインストールした直後にコンパイルエラーになってしまったのでますます不思議です。



rabbitcats at 00:59|PermalinkComments(0)TrackBack(0)

2014年11月26日

動的にアイコンを変えられるツールバー

C++ でMFC を利用してデスクトップアプリケーションの開発をしていた時の覚書です。
画面を切り替えて使うアプリケーションなどでは、画面ごとに似たような機能を持ったツールバーを用意することがあると思います。
その場合に一つのツールバーで見た目と機能を切り替えると便利かと思ったので、試してみました。

下準備

CMFCToolBar を継承した新しいToolBar クラスを作成し、下記の関数をオーバーライドします。

BOOL CMyToolBar::LoadToolBar(UINT uiResID, UINT uiColdResID, UINT uiMenuResID, BOOL bLocked,
        UINT uiDisabledResID, UINT uiMenuDisabledResID,  UINT uiHotResID)
{
    m_uiOriginalResID = 0;
    return CMFCToolBar::LoadToolBar(uiResID, uiColdResID, uiMenuResID, bLocked, uiDisabledResID, uiMenuDisabledResID, uiHotResID);
}

BOOL CMyToolBar::LoadToolBarEx(UINT uiToolbarResID, CMFCToolBarInfo& params, BOOL bLocked)
{
    m_uiOriginalResID = 0;
    return CMFCToolBar::LoadToolBarEx(uiToolbarResID,params,bLocked);
}

実際にはLoadToolBar は内部でLoadToolBarEx を呼び出しているので、LoadToolBarEx だけオーバーライドすればできると思います。
動的にアイコンを変えたい場合にはm_uiOriginalResID の値を0 にしてあげる必要があります。
これはCMFCToolBar::LoadToolBarEx 内でビットマップをロードするLoadBitmapEx と同じ条件式のところで、m_uiOriginalResID の値を見ているからです。

if (m_uiOriginalResID != 0 || LoadBitmapEx(params, bLocked))

afxtoolbar.cpp のLoadToolBarEx 内でこのようにコードが書かれています(VisualStudio12.0で確認)。 m_uiOriginalResID が0 以外の場合ではLoadBitmapEx が呼び出されないため、変更したいツールバーのビットマップが読み込まれないことになってしまいます。

使い方

使い方は簡単で、いつも通りツールバーを作成します。

m_pMyToolBar->CreateEx(
    this,
    TBSTYLE_FLAT,
    WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,
    CRect(0, 0, 0, 0),
    MYTOOLBAR1_ID
    );
m_pMyToolBar->LoadToolBar(IDR_MYTOOLBAR1, 0, 0, TRUE);
m_pMyToolBar->SetWindowText(_T("MyToolbar1"));
m_pMyToolBar->SetControlBarStyle(m_pMyToolBar->GetControlBarStyle() & ~AFX_CBRS_CLOSE);

this->DockPane(m_pWndToolBar.get());

そのあとに変更したいタイミング(たとえばツールバーのアイコンをクリックしたタイミングなど)で下記のコードを呼び出します。

m_pMyToolBar->CleanUpLockedImages();
m_pMyToolBar->LoadToolBar(IDR_MYTOOLBAR2, 0, 0, TRUE);
m_pMyToolBar->AdjustLayout();
m_pMyToolBar->AdjustSizeImmediate();

これで無事にツールバーを変更することができます。

おまけ

実は上に書いたコードには落とし穴がありました。
ツールバーを作成した後に
m_pMyToolBar->SetControlBarStyle(m_pMyToolBar->GetControlBarStyle() & ~AFX_CBRS_CLOSE);
でツールバーの閉じるボタンを無効に設定しているのですが、実際には閉じるボタンは表示されてしまいます。

CMFCToolBar::CanBeClosed

CanBeClosed で閉じることができるかどうかを判断できるのですが、CMFCToolBar は常にTRUE を返すようです。
ちょっと意味が分からないですね。
そこで、とりあえず下記のようにオーバーライドすることで設定した値で判断するように変更できます。

BOOL CMyToolBar::CanBeClosed() const
{
    return CBasePane::CanBeClosed();
}

これで解決できるのですが、良いのかどうか・・・



rabbitcats at 00:50|PermalinkComments(0)TrackBack(0)

2012年10月02日

VS10でCUDAプロジェクトをビルドしたときのエラー(MSB3721)について

連続で技術的なことを記事にするのは珍しいですね。
困っている方が多そうなのでメモ程度ですが、CUDAのビルド時のエラーについての対策を書いておきます。

VS10でC++とCUDAの両方を用いて開発をする際に以下のエラーが出ることがあります。

C:\hoge\CUDA 4.2.targets(361,9): error MSB3721: コマンド (中略) gpu.cuh はコード -1 で終了しました。

ソースコードはmain.cpp、gpu.cu、gpu.cuh の3つです。
ちなみに中身は続きに書いてあります。

エラーはcuhファイルのプロパティから構成プロパティ->全般->項目の種類 のところをCUDA C/C++ からC/C++ コンパイラまたはC/C++ ヘッダーに変更すればとりあえずはエラーなくビルドができるようになると思います。

cuh ファイルをcl.exeでコンパイルするのが気持ち悪いと感じたら、hファイルに変えても動きます。
適当なコンパイラなら拡張子はなんでもいいみたいですね。

対策の一つとしてやってみるとうまくいくかもしれません

2012/10/14
include ファイルの消えていた部分の修正、ファイル名が違っていたので修正

続きを読む

rabbitcats at 14:41|PermalinkComments(0)