Hatena::ブログ(Diary)

hishidaのblog このページをアンテナに追加 RSSフィード

プロフィール

hishida

hishida

EB series support page 管理人 ブログ

2018-02-25

[][][]EBWin4 64bit版

要望を頂いている訳ではないが、EBWin4の64bit版を実験的にビルドしてみた。

WindowsクライアントOSではVistaから64bit版が提供されるようになり、現在ではインストールベースで64bitが32bit版を上回っている。32bitOSでは物理メモリが3GBが上限だが、64bitなら物理メモリの上限まで使用できる。

ちなみにmac OSもHigh Sheirraが32bitアプリが動作する最後のOSと告知されており、iOSもiOS11から32bitはもはや実行できない。Windowsアプリもいずれは64bit対応が必須になるだろう。

EBMacやEBPocketはすでに64bit化が済んでおり、EBWin4もそろそろ64bitネイティブ化する時期だと思う。

既存の32bitアプリを64bit化する手順は、

本当に64bitで動いているかどうかは、タスクマネージャで確認できる。

1日くらいの作業で64bit化できたが、私の通常の使用環境だと32bitとの違いは全然感じない。数十個の辞書をグループ化して検索するような極端なケースでは、多少恩恵があるかもしれない。

次の目標はEBStudio2の64bit化になるが、これは4GB超の巨大辞書を作るときに必要になると思う。

P.S.

EBStudio2の64bit版も2/27にリリースしました。特に問題はないように見えます。

2017-07-17

[] Visual C++2010ランタイムインストーラに含める方法

EBWin4はVisual Studio 2010 のC#C++で開発しているため、実行には.Net Framework 4.0とVisual C++ 2010 ランタイムが要る。

.Net Framework 4はWindows Vista以降は標準でWindowsに含まれているため、通常はインストールの必要はない。

だがVisual C++ 2010 ランタイムWindows に含まれていないため、別途ユーザに「Visual C++ 2010 再配布可能パッケージ(x86)」をインストールしてもらわないといけない。やっかいなことに、Visual C++ はバージョンごとにランタイムが違い、さらに32bit(x86)版と64bit版(x64)が存在する。EBWin4のREADMEには対応するバージョンの再配布可能パッケージのリンクが書いてあるが、利用者にとって敷居が高いことは事実である。

これまでインストーラにはフリーの Inno Setup を使っていたが、Visual Studioインストーラを使用すれば、必須コンポーネントインターネットから自動インストールするようにできるので、今回からインストーラを変更することにした。

Visual Studioインストーラの作り方

ここでインストールする必須コンポーネントVisual Studio 2010ランタイムライブラリ(x86)を追加する。(なお、必須コンポーネントインストーラに含めるか、インターネットからダウンロードするかを選ぶことができる。)

インストーラの本体は.msiだが、setup.exeはコンピュータに必須コンポーネントがあるかどうかを調べ、インストールされていなければ次のような画面が出て、インターネットからダウンロードしてインストールまで行う。

f:id:hishida:20170717162740p:image

これで起動トラブルは減ると思う。

ここで一つ問題があって、Visual Studio 2010にはSP1が提供されており、2010無印と 2010 SP1とでランタイムライブラリが異なる。再配布可能パッケージも2010無印と2010 SP1の2種類が存在する。

Download Microsoft Visual C++ 2010 再頒布可能パッケージ (x86) from Official Microsoft Download Center

Download Microsoft Visual C++ 2010 SP1 再頒布可能パッケージ (x86) from Official Microsoft Download Center

ユーザのコンピューターにVisual C++ 2010 SP1のランタイムが先に入っていた場合、 「より新しいバージョンのMicrosoft Visual C++ Redistributableがコンピューター上で検出されました」 と表示されてインストールが止まってしまう。

この場合は.msiを実行していただければ、EBWin4の本体だけインストールされる。

Visual Studio 2015 Installer Projects

Visual Studioインストーラはその後、Visual Studio 2012 で削除されてInstallShield LEだけになったが、 Visual Studio 2013から復活した。ただしVisual Studio Marketplaceから別途インストールする必要がある。現在のVisual Studio Community 2015でも使用できる。

Microsoft Visual Studio 2013 Installer Projects の設定方法について - マコーの日記

no title

補足:Inno setup でVisual C++ ランタイムを自動インストールする方法

なお、Inno setup でもスクリプトを書けば、Visual C++ Redistribuableのインストール有無をチェックして自動インストールすることができる。

inno setup - How to make vcredist_x86 reinstall only if not yet installed? - Stack Overflow

ただし、vcredist_x86.exeはあらかじめダウンロードしてパッケージに含めなければならない。

2017-07-12

[] xdoc2txt の64bit版

ユーザからの要望があって、xdoc2txtおよびdllの64bit版を作成したので、忘備録を書いておく。

x64コンパイラおよびツールのインストール

Visual Studio 2010を標準でインストールすると、64ビット用コンパイラはインストールされないので、インストール時のオプションで「x64コンパイラおよびツール」を指定してインストールする。

f:id:hishida:20170712084244p:image

既存のプロジェクトの64bit化

32bit版の既存のプロジェクトを64bit化する場合の手順。

  • 32bit版の既存のプロジェクトを読み込んだ後、メニュー→ビルド(B)→構成マネージャー(O)を起動
  • アクティブソリュージョン構成(C)→新規作成...を選び、64bit用の新しいソリュージョン構成を作成する。名称は例えば"Release x64"とする。この時設定のコピー元に(32bitの)既存のソリュージョンを選択すると、ソリュージョンがコピーされる。
  • アクティブソリュージョンプラットフォーム(P)→新規作成

新しいプラットフォームを入力または選択してください(P) : x64

設定のコピー元 : Win32

EXE、LIB、DLLも全て同様の手順で64bit化される。

注意点は、32bitのDLLと64bitのDLLを混ぜて使うことはできないので、関連するDLLライブラリは全て64bitで揃える必要がある。xdoc2txtは内部でzlib1.2.3を使用しているので、zlib1.2.3もソースから64bitで再コンパイルした。

またVisual C++の64bit版を使用してコンパイルしたモジュールを実行する場合、Visual C++ 再頒布可能パッケージもx64用をインストールする必要がある。

32bit版Download Microsoft Visual C++ 2010 再頒布可能パッケージ (x86) from Official Microsoft Download Center
64bit版Download Microsoft Visual C++ 2010 再頒布可能パッケージ (x64) from Official Microsoft Download Center

一般的な注意

Visual C++ の64bit版の一般的な注意は、

  • 64 ビット Windows OS上ではポインタは64bitだが、int と long は相変わらず32bit ( 64bit整数は__int64 または long long ! )。したがってポインタをintやlongに代入してはいけない。
  • size_t、time_t、 ptrdiff_t は、64 ビット Windows OS上では 64 ビット。したがってtime_tをlongに代入してはいけない。

C# で64bit版のdllを使用する場合の注意点

C#のプロジェクトのプラットフォームターゲットはデフォルトではx86になっているため、デフォルトのままだと32ビット版のdllしか読み込まない。C#から64bitのdllを呼び出す場合は、プラットフォームターゲットをAnyCPUに変える。

2016-12-01

[][][]EBWin4 の高DPI化について

EBWin4の高DPI化を行ったので、忘備録として作業内容をまとめておこうと思う。

事の発端は、Macbook pro retina 13" Early2015を購入したこと(2016-11-19 - hishidaのblog)。retinaディスプレイではVMWare Fusion上のWindowsの文字が極端に小さくなり、文字サイズを拡大しないと使用できなくなった。

Macbook pro retina 13"の実解像度は2560x1600だが、Mac OS Xでは擬似解像度1280x800にスケーリングされて表示される。だがVMWare 上のWindowsではドットバイドットで表示されるので、2560x1600の実解像度のまま表示され、文字が小さくなってしまう。

「ディスプレイ設定」→「テキスト、アプリ、その他の項目のサイズを変更する:」で150%〜200%に拡大すると、DPIのスケーリングに従ってアプリも拡大されて表示される。だがEBWin4のように高DPIに対応していないアプリだと、下図のように文字がにじんで表示されてしまう。Surface Proなどの高解像度の端末では、以前から問題になっていたと思う。

図:高DPIに対応していない場合、文字サイズを拡大するとにじんで表示される:

f:id:hishida:20161202110628p:image

Windows Form アプリの高DPI化作業について

高DPI化全般については、下記のマイクロソフトの田中達彦氏のブログが詳しい。

アプリの高DPI(High DPI)対応について 第1回 ~ 高DPIとは ~ – 田中達彦のブログ

WPFで開発したソフトは自動的にdpiAwareになるが、昔ながらのWindows Formで開発したソフトは、デフォルトでは高DPIに非対応となる。

Windwos FormでアプリをdpiAwareにする方法は簡単で、前述のブログにあるように、app.manifestを追加してdpiAwareをtrueにすればいい。

app.manifestは、Visual Studio でプロジェクトで右クリック→追加(D)→新規項目(W)で簡単に追加できる。

ただしdpiAwareの雛型が作られるのはVisual Studio 2013以降なので(現行のVisual Studio Community 2015もOK)、Visual Studio 2010以前のバージョンを使用している場合は、記述を手動で追加する必要がある。

app.manifestに追加した記述:

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>

基本的には、これだけでdpiAwareになり、文字サイズを拡大しても文字がにじまなくなる。

ただEBWin4の場合はEPWINGの外字をビットマップイメージで表示しており、文字サイズを変えても外字ビットマップは小さいままなので、表示のバランスが非常に悪くなる。

つまり現在のWindowsの文字サイズの倍率を取得して、ビットマップ画像も拡大しなければならない。

様々なサイトを参考にして、現在のDPIを取得するサポートクラスを追加した:(100%なら96dpiを返す)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;


namespace EBWin4
{
    public static class ScreenExtensions
    {
        public static void GetDpi(this System.Windows.Forms.Screen screen, DpiType dpiType, 
                   out uint dpiX, out uint dpiY)
        {
            try
            {
                var pnt = new System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1);
                var mon = MonitorFromPoint(pnt, 2/*MONITOR_DEFAULTTONEAREST*/);
                GetDpiForMonitor(mon, dpiType, out dpiX, out dpiY);
            }
            catch
            {
                dpiX = 96;
                dpiY = 96;
            }
        }

        //https://msdn.microsoft.com/en-us/library/windows/desktop/dd145062(v=vs.85).aspx
        [DllImport("User32.dll")]
        private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);

        //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
        [DllImport("Shcore.dll")]
        private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);
    }

    //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280511(v=vs.85).aspx
    public enum DpiType
    {
        Effective = 0,
        Angular = 1,
        Raw = 2,
    }
}

上記クラスを使用して、現在の文字サイズのスケールを取得する関数

        /// <summary>
        /// ScreenのDPIスケールを得る
        /// </summary>
        /// <returns></returns>
        private double GetDPIScale()
        {
            double dpiScale = 1.0;
            try {
                //  現在フォームのあるスクリーンを得る
                System.Windows.Forms.Screen s =
                    System.Windows.Forms.Screen.FromControl(this);
                uint x, y;
                s.GetDpi(DpiType.Effective, out x, out y);
                dpiScale = ( x / 96.0);
            }
            catch {
            }
            return dpiScale;
        }

DPIスケールに合わせて画像を拡大する関数:

      /// <summary>
        /// DPIに応じて拡大したImage画像を作成
        /// </summary>
        /// <param name="image"></param>
        /// <param name="dpiScale"></param>
        /// <returns></returns>
        private Image GetImageStretchedDPI(Image image, double dpiScale)
        {
            Size newSize = image.Size;
            newSize.Width = (int)(newSize.Width * dpiScale);
            newSize.Height = (int)(newSize.Height * dpiScale);

            Bitmap newBitmap = new Bitmap(image, newSize);

            image.Dispose();
            return newBitmap;

        }

これで高DPIで美しく文字が表示されるようになった。

図:高DPI化されたEBWin4

f:id:hishida:20161202110623p:image

高DPI時代のEPWINGビューアとして、もうしばらく延命できることとなった。

2016-07-19

[][]Visual Studio Community2015 を入れた

どうも最近、開発環境の整備に時間を費やして、肝心の開発が何も進んでいないようだ。

1 Windows10の導入

Windows 10への無料アップデートの期限が7月29日までということで、重い腰を上げて、開発環境をWindows7からWindows10にアップグレードすることにした。

当方の環境はMac OS XのVMWare Fusionなので、これまで使用していたWindows7の仮想イメージは外付けハードディスクにバックアップして削除し、Macbook proのディスクスペースを空ける。

手元にはMSDNに加入していた時に送られてきたWindows8.1のDVDとライセンスキーがある(今はMSDNに加入してもDVD郵送サービスはないので、貴重だ)。

なるべくクリーンなWindows10を入れたいので、Windows8.1をクリーンインストールしてからWindows10にアップデートすることにした。なお、MSDNの期限が切れていても、当時取得したWindows8.1のライセンスキーは現在も有効である。

Windows10インストール直後はWindows標準のディスプレードライバのために表示が非常に遅かったが、VMWare Toolsを再インストールするとVMWare SVGA 3D ドライバに更新され、快適に表示できるようになった。Windows10仮想マシンにはメモリ4Gと2CPUを割り当てる。実用上ほとんど不満を感じない。

Microsoft OfficeはOffice2010の優待アップグレード版のOffice2013を導入。日常的な使用環境はこれで整った。

2 Visual Studio Comminuty 2015の導入

さて開発ツールだが、個人ユーザなら無料で使用できるVisual Studio Community 2015を導入。(過去 Visual Studio Professional with MSDN を3回も購入した者としては、いい時代になったものだと思う。まあMSDNにはOSも付いているけど。)

これまで開発したプロジェクトをコンパイルするための保険にVisual Studio2010も入れたが、Visual Studio Community 2015ではVS2010のプロジェクトをそのまま読み込んでVS2010のライブラリセットを指定してコンパイルできるので、VS2010は不要かもしれない。

3 EBPocket for WinRTのWIndows8.1アプリへの移行

以前、VS2012でWindows8ストアアプリのEBPocket for WinRTを開発してリリースしたが、ストアアプリの将来性に疑問を感じて開発を凍結していた。

その後、VS2013ではWindows8.1とWindows Phone8.1のユニバーサルアプリが作れるようになり、VS2015では同一バイナリですべてのWindowsプラットフォームで動作するUWPが登場。あっという間に2世代も進んでしまった。

今回最初に行ったことは、Windows8ストアアプリのEBPocket for WinRTの当時のソースを、Visual Studio Community 2015でコンパイルすることである。

VS2012で作成したWindows8用のプロジェクトを読み込むと、Windows8.1に再ターゲットを求められる。EBPocketの本体のソースはWindows8.1に再ターゲットできたが、C++/CXで開発したWindowsランタイムライブラリが変換できない。

仕方ないので新規プロジェクトでユニバーサルWindows8.1のWindowsランタイムコンポーネントを作り、ソースを一つ一つ追加。これでコンパイル&リンクしたところ、EBPocket for WinRTがWindows8.1アプリとして復活した。Windows10では全画面ではなく一つのウインドーで動くので、かなり使い勝手がよくなった気がする。(もちろん機能が少ないことを酷評されていることは承知しているが。)

4 ストアアプリの将来について

Windows8.1アプリになったといっても、Windows8.1ユニバーサルアプリとしてWindows Phone8.1版を追加するのは、アプリ一本をまるまる新規で開発するぐらいの工数がかかる。いっそUWPで単一のEBPocket for UWPを作った方がいいのではないか。

そう考えてUWPの新規プロジェクトを試してみると、Windows8.1ストアアプリにあったような「分割アプリ」「ハブアプリ」のようなテンプレートがない。要するにどんな解像度でも動くように、自分で様々な解像度にあった画面を用意しないといけないらしい。ここでまたやる気が萎えてしまった。

この1年くらいでWindows Phoneの新機種が日本でも発売されるようになったが、シェアが低いのは相変わらずで、「アプリがないからシェアが低い、シェアが低いからアプリが作られない」というジレンマから抜け切れていない。UWPも開発事例が少ないようで、笛吹けど踊らずの状態がまだ続くかもしれない。

やはりWindows Mobileに対する方針の迷走と、過去のアプリの互換性を切り捨てたことによる開発者離れがいまだに効いていると思う。懐かしいW-ZERO3の頃には、スマートフォンのシェア100%だったのだから。当時の有名アプリで今もWindows Phoneで開発が続いているのは青空子猫ぐらいじゃないか。

EBPocket for WinRTを再開するための開発環境の構築まではできた。この後やる気がでるかどうかは、まだなんとも言えない。Windows Phoneの実機はお安いようだが。。。