Windows 7 のデスクトップヒープサイズは?

2011 年になりました。今年もマイペースでブログを更新していこうと思います。
最初なので、小ネタです。何気に Windows 7 のデスクトップヒープサイズを調べていたのですが
知らぬ間に以前の OS からデフォルトサイズが変更(3MB→12MB)されていました。
よくよく調べてみると、Windows Vista SP1 以降で変更が入ったとのこと。(もちろん、32bit OSでの話し)

デスクトップヒープサイズ

  • x86
    Windows Vista SP1 以降の OS で 12MB
    Windows Vista RTM 以前の OS(サーバー OS 含む)で 3MB
  • x64
    現状の x64 版 OS(クライアント OS & サーバー OS 共)では、すべて 20MB

サイズの確認方法ですが、レジストリエントリーを見ると、わかります。

HKEY_LOCAL_MACHINE
 System
  CurrentControlSet
   Control
    Session Manager
     SubSystems

ここのレジストリーキーにある Windows という値のデータを見ます。Windows 7 (x86) では次のようになっています。

%SystemRoot%\system32\csrss.exe
ObjectDirectory=\Windows
SharedSection=1024,12288,512
Windows=On
SubSystemType=Windows
ServerDll=basesrv,1
ServerDll=winsrv:UserServerDllInitialization,3
ServerDll=winsrv:ConServerDllInitialization,2
ServerDll=sxssrv,4
ProfileControl=Off
MaxRequestThreads=16

上記の赤字の部分がデスクトップヒープのサイズを示しています。

ううう、変更されたの知らなかった…。

Win7: Windows 7 らしい UX(TaskDialog 編)

エンタープライズ分野でも Windows 7 対応アプリケーションが増えてきました。
ただ、ほとんどが互換性を重視するもので、UX も、Windows 7 に最適化されているものではなく
ちょっと残念な気がします。

そこで、ほんのちょっとの変更で、Windows 7 らしい UX に対応できる Tips をいつくか紹介しようと
思います。まずは、TaskDialog を紹介します。
(ちなみに、TaskDialog は、Windows Vista からサポートされています)

そもそも、TaskDialog ってなんだ?ってことになるのですが、一言で言えば、ゴージャスなメッセージボックスです。
いや、まじめに書きます。

タスクダイアログですが、Vista 以降、メッセージボックスに置き換わるものとして提供されています。
メッセージボックスは単純なユーザー応答(はい/いいえ/キャンセル)だけを求めるものでしたが、
タスクダイアログは、もっと幅広くユーザーからの情報を収集するために使用するという位置づけになりました。
(これもエクスペリエンスの 1 つです)
要は、”メッセージボックス以外の機能であれば、ダイアログを開発者が作ってね”というものを
”OS 機能として提供するから使ってね”ということです。

まずは、お馴染みのメッセージボックスから。

この投稿の続きを読む

Touch Pack for Windows 7 が公開されました

以前より、Windows Touch については、個人的にも非常に追及しているわけですが、
Microsoft より、OEM プレインストール向けにリリースされていた Windows Touch アプリケーションが
一般公開されました。
すべて、非常に完成度の高いアプリケーションになっています。

この Touch Pack ですが、HP の IQ シリーズにはプレインストールされていたようです。
私もデモで HP の IQ シリーズを使った際に、いじったので。

この中で、一番のおすすめは、Surface Globe です。地球儀を指タッチで ”ぐるぐる” できます。
やはり、何か、キラーアプリに相当するものが無いと、マルチタッチも実感が湧きませんよね。

あっ、もちろん、Touch Pack を動かすには、マルチタッチに対応したモニターが無いとだめです。
過去に幾つか、このブログでもマルチタッチモニターを紹介したので、ご参考に。

Win7: ログオン画面の背景をカスタマイズ

Windows 7 のカスタマイズネタです。Windows 7 のログオン画面ですが、普段はこんな画面ですよね。

皆と同じじゃ嫌だ!自分のオリジナル色を出したい!という方は多いでしょう。
では、この画面(背景)を変更するカスタマイズを紹介します。

  1. 使用したい JPG ファイルを用意する。なお、サイズは 256KB 以下という制限があります。
  2. ファイル名を backgroundDefault.jpg という名前に変更する。
  3. エクスプローラーを開き、以下のフォルダを作成する。
    「 \system32\oobe\info\backgrounds 」
    oobe というフォルダを作成しようとすると、”すでに、そのフォルダ名は存在します。統合しますか?” のような
    メッセージが表示されますので、”はい” で進めてください。
    (oobe というフォルダはすでに隠しフォルダで存在しています)
  4. 作成したフォルダに、用意した backgroundDefault.jpg ファイルを保存する。
  5. レジストリエディタ(regedit.exe)を実行し、以下のレジストリを変更する。

HKLM\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Background@OEMBackground = 1

  • 以上の設定が終了したら、Windows をログオフする。
  • これで、ログオン画面が変更されているはずです。

    少しだけオプション設定があります。
    先ほどのレジストリと同じ場所に

    HKLM\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Background@ButtonSet

    という DWORD 値を作成して、その値を変更することで、若干ですが、コントロールの色を変更することができます。

    • ButtonSet = 0 : デフォルト
    • ButtonSet = 1 : 明るい背景用のボタンセット
    • ButtonSet = 2 : 暗い背景用のボタンセット

    ログオン画面をあまり長い時間見ることは無いと思いますが、こんなカスタマイズで楽しんでみるのもいいかもしれません。
    あと、お約束ですが、レジストリの変更には、くれぐれも注意してください。

    Win7&2008R2: Problem Steps Recorder を使う

    Windows 7 & 2008 R2 には、トラブルシューティング用のツールとして、Problem Steps Recorder という
    ものがバンドルされています。日本語だと、「問題ステップ記録ツール」となっています。
    何をするものなのかというと、”操作を記録するレコーダー” です。
    結構、便利です。ユーザーにどんな操作なのかを聞くよりも、これで記録してもらい、それを確認する方が
    早いかもしれません。
    トラブルシューティング用のツールですので、使い方は非常に簡単です。

    1. いきなりですが、”ファイル名を指定して実行” から、psr.exe と入力します。(なぜか、メニュー登録されていない…)
      すると、こんな画面が起動します。

       

      容易に想像できると思いますが、”記録の開始” をクリックします。
      ただ、このままだと、「問題ステップ記録ツール」は、管理者権限のアプリケーションの操作を記録することが
      できませんので、できれば、最初から、psr.exe を管理者権限で起動しておくことをおすすめします。

    2. ”記録の開始” をクリックして、操作を記録します。簡単ですね。
    3. 操作が終わったら、”記録の停止” をクリックします。すると、記録したファイルを保存するために
      ”名前を付けて保存ダイアログ” が表示されます。

       

      拡張子を見てわかるように、ZIP ファイル形式で保存します。

    4. では、どのようなファイルになっているのかを見てみましょう。先ほど、保存した ZIP ファイルを
      解凍してみます。すると、Problem_YYYYMMDD_HHMM.mht という形式の単一ファイルが解凍されます。
      ファイルを開いてみると、こんな感じです。

       
      デスクトップ全体がキャプチャーされています。また、マウスの位置(クリックした部分)も緑色の枠で
      囲われているため、何をやったのかがすぐにわかると思います。

    結構、便利なツールなので、ぜひ、活用してみてください。

    Win7: タスクバープログラミング(AppIDs)補足

    以前、Win7: タスクバープログラミング(AppIDs)を紹介しました。
    肝心なことを書き忘れたので、補足記事を書きます。

    Application Identity の機能ですが、これは「タスクバーの設定」に依存しますので、注意が必要です。
    タスクバーは、ユーザーによってその動作をカスタマイズすることができます。

    いまいち、Windows 7 の新タスクバーにどうも馴染めないという方も中にはいるかもしれません。
    そのような人は、従来のタスクバーに似せようとして

    タスバーのデザイン: 小さいアイコンを使う
    タスクバーのボタン: “タスクバーがいっぱいの場合に結合” or “結合しない”

    という設定にするかもしれません。すると、表示が Vista/XP 風になります。

    このような設定の場合、Application Identity のプログラミングを行い、同じ Application Identity に設定しても
    アプリケーションアイコンは結合されませんので注意してください。

    さらに、もうひとつ注意点があります。この設定にした場合、Aero プレビューが、こんなのになっちゃいます。

    どうやら、Application Identity を同じにすると、Aero プレビューだけは同じグルーピングされてしまうようです。

    Application Identity を同じにして、アプリケーションアイコンをひとつにまとめるという実装を行う場合には、
    ユーザーが「アプリケーションアイコンをまとめる/まとめない」という選択ができるような設定画面を
    提供した方がよいと思います。

    Win7: タスクバープログラミング(オーバーレイアイコンとプログレスバー)

    タスクバープログラミングの第二弾です。
    今回は、オーバーレイアイコンとプログレスバーに関するネタです。

    • タスクバーへのオーバーレイアイコン
      • プログラムアイコンに重ねて表示することができる

    • タスクバーへのプログレスバー
      • プログラムアイコンの背景をプログレスバーとして表示することができる

    イメージがわかってもらえたと思います。
    まずは、オーバレイアイコンの実装方法を説明します。

    タスクバーへのオーバーレイアイコンですが、ITaskbarList3 インターフェースにある SetOverlayIcon メソッドを使用します。

    使い方は非常に簡単です。(コードを簡潔にするために ATL を使っています)

    CComPtr<ITaskbarList3> m_ptrTaskbarList3;
    HICON m_hOverlayIcon; // アイコンリソースハンドル
    ・・・
    LRESULT CMainDlg::OnInitDialog(UINT, WPARAM, LPARAM, BOOL& )
    {
        ・・・
        // オーバーレイアイコンの読み込み
        m_hOverlayIcon = (HICON)LoadImage(_Module.m_hInstResource,
                            MAKEINTRESOURCE(IDI_OVERLAY),
                            IMAGE_ICON,
                            ::GetSystemMetrics(SM_CXICON),
                            ::GetSystemMetrics(SM_CYICON),
                            LR_DEFAULTCOLOR);
    
        // ITaskbarList3 インターフェースのアクティベート
        HRESULT hRes = m_ptrTaskbarList3.CoCreateInstance(CLSID_TaskbarList);
        ATLASSERT(SUCCEEDED(hRes));
        ・・・
    }
    
    void CMainDlg::SetTaskbarOverlayIcon(BOOL b)
    {
        HRESULT hRes;
        if (b)
        {
            // オーバーレイアイコンの表示
            hRes = m_ptrTaskbarList3->SetOverlayIcon(
            m_hWnd, m_hOverlayIcon, TEXT("ErrorInformation"));
        }
        else
        {
            // オーバーレイアイコンを消す
            hRes = m_ptrTaskbarList3->SetOverlayIcon(
            m_hWnd, NULL, TEXT("AppDemo2"));
        }
        ATLASSERT(SUCCEEDED(hRes));
    }

    上記コードのように、SetOverlayIcon メソッドを使い、アイコンリソースハンドルを指定するだけです。
    アイコンを消す場合には、アイコンリソースハンドルを NULL に指定します。

    次に、プログレスバーの実装方法を説明します。これも ITaskbarList3 インターフェースを使います。
    このインターフェースにある SetProgressState メソッドと SetProgressValue メソッドを使用します。

    先ほどと同じようにコードサンプルを載せておきます。(コードを簡潔にするために ATL を使っています)

    CComPtr<ITaskbarList3> m_ptrTaskbarList3;
    UINT m_uTimerID; // タイマー識別子

    UINT m_nRef;
    WTL::CProgressBarCtrl m_ProgressBar;

    ・・・
    LRESULT CMainDlg::OnInitDialog(UINT, WPARAM, LPARAM, BOOL& )
    {
        ・・・
        // ITaskbarList3 インターフェースのアクティベート
        HRESULT hRes = m_ptrTaskbarList3.CoCreateInstance(CLSID_TaskbarList);
        ATLASSERT(SUCCEEDED(hRes));
        m_ProgressBar.Attach(GetDlgItem(IDC_PROGRESS));
        ・・・
    }
    LRESULT CMainDlg::OnBnClickedProgressBar(WORD, WORD, HWND, BOOL& )
    {
        // タスクバー プログレスバーの値をトータルで 100 に設定
        m_ptrTaskbarList3->SetProgressValue(m_hWnd, 0, 100);
        ・・・
        // タイマーの仕込み
        m_uTimerID = SetTimer(UM_TIMEREVENT, 500);
        if (m_uTimerID == 0)
        {
            DWORD dwErr = GetLastError();
            // エラー処理
        }
        return 0;
    }
    LRESULT CMainDlg::OnTimer(UINT, WPARAM wParam, LPARAM, BOOL& )
    {
        if (wParam == UM_TIMEREVENT)
        {
            m_nRef++;
            ・・・
            // タスクバー プログレスバーの色を指定する
            m_ptrTaskbarList3->SetProgressState(m_hWnd, TBPF_NORMAL);
            // タスクバー プログレスバーの位置を進める
            m_ptrTaskbarList3->SetProgressValue(m_hWnd, m_nRef * 5, 100);
            if (m_nRef == 20)
            {
                ClearTimerEvent(); // この中で KillTimer() を呼んでいる
                m_nRef = 0;
                ・・・
            }
        }
        return 0;
    }

    タスクバー プログレスバーの色ですが、SetProgressState メソッドを呼び出す際のパラメーターで制御することができます。
    上記コードでは、TBPF_NORMAL を指定しています。この場合、グリーンで表示されます。
    TBPF_ERROR を指定するとレッドになり、TBPF_PAUSED を指定するとイエローになります。

    Windows 7 タスクバーに表示されるアイコンですが、マウスを Hover した際、プログラムアイコンの色をベースに
    Hover 色が決定されます。

    MSDN フォーラムでも回答したのですが、タスクバー プログレスバーを使う際には、プログラムアイコンのデザインで
    あまり、グリーン、レッド、イエローを使わない方がいいかもしれません。
    でないと、せっかく、プログレスバーにステータス表示しているにもかかわらず、よく見えないということになってしまい
    本末転送になってしまいます。

    オーバーレイアイコンやプログレスバーは、プログラムの状態を表示する非常によい手段だと思います。
    Windows 7 対応のアプリケーションでは、ぜひ、実装してみてはいかがでしょうか。

    Win7: タスクバープログラミング(AppIDs)

    ようやくタスクバープログラミングを書きます…。
    Windows 7 のタスクバーに関する前置きは、過去の記事を参考にしてください。

    今回は、”Application Identity による管理” ということで、Application Identity(AppIDs とします)に関する
    プログラミングのネタです。
    Windows のタスクバーですが、プログラムを起動すると、プログラムアイコンがタスクバーに表示されます。
    同じプログラムを複数起動した際にはグルーピングされるわけですが、このグルーピングの際、プロセス(exe)名で
    管理しているのではなく、Windows は Application Identity という単位で管理しています。
    つまり、別の言い方をすると、同じ Application Identity であればグルーピングするという仕様になっているわけです。
    そして、Windows 7 では、この Application Identity を任意で変更できるようになりました。

    AppIDs は、プロセスのメインウィンドウを生成する際にプロセス名をベースにして OS によって割り当てられます。
    (↓セミナーで使っているスライドからの抜粋です)

     
    この AppIDs によるグルーピングですが、例えば

    1. 異なるプロセスだが、ひとつのグループにまとめたい
    2. 同じプロセスだが、起動引数によって意味が異なるので、グルーピングしたくない

    などのようなシナリオの場合には、AppIDs をカスタマイズすることで、今までの Windows にはできなかった動きを
    実装することができます。

    わかりやすくするために、画面を使います。
    まずは、グルーピングされているイメージです。この 2 つのプロセス名は異なっていますが、Application Identity を
    ”MyDemo2009Apps” と同じにすることで、アプリケーションアイコンをひとつだけ表示するようにしています。

    次に、片方の Application Identity を “MyDemo2009Apps2“ に変更してみます。

    するとアプリケーションアイコンが 2 つに分離します。これで動きがわかってもらえるかなと思います。

    AppIDs については、次の 2 つの API が用意されています。(かなり長い名前の API デス)

    使い方は非常に簡単です。

    [Application Identity を設定する]

    ネイティブコードで書くなら、WinMain の直後や メインウィンドウを生成する(WM_CREATE 内)が適切です。
    .NET Windows フォームであれば、フォームのコンストラクタや Load イベント内が適切です。

    int WINAPI _tWinMain(
      HINSTANCE hInstance,
      HINSTANCE /*hPrevInstance*/,
      LPTSTR lpstrCmdLine,
      int nCmdShow)
    {
      // アプリケーション ID 名称
      PCWSTR pcwstrAppID = TEXT(“MyDemoApps2009“);
      // アプリケーションに AppID をカスタム設定
      SetCurrentProcessExplicitAppUserModelID(pcwstrAppID);
    
    ・・・

    [Application Identity を取得する]

    任意のタイミングで取得できます。

    WCHAR szAppId[129];
    WCHAR * psz = szAppId;
    HRESULT hRes = GetCurrentProcessExplicitAppUserModelID(&psz);
    if (SUCCEEDED(hRes))
    {
        m_edAppId.SetWindowText(psz);
    }
    else
    {
        m_edAppId.SetWindowText(TEXT("Unknown Application ID"));
    }

    ただし、Application Identity には、次の注意点があります。

    • OS が割り当てた既定の Application Identity は取得できない
    • Application Identity の最大文字列長は 128 byte
    • Windows Vista モードでも有効
    • 必ず、タスクバーにアイコンが表示される前に設定する必要がある

    では、任意のタイミングで Application Identity を設定/変更することができるのかというと、一応できます。
    ただし、あまり推奨されていません。
    実は、SetCurrentProcessExplicitAppUserModelID() を任意のタイミングで発行しても Application Identity は変わらないのです。
    この API が有効なのは、タスクバーにアイコンが表示される前だけなのです。
    では、どうするのかというと、Shell のプロパティストアに格納されている ID を強制的に変更してあげることになります。

    [任意のタイミングで Application Identity を変更する]

    コードを簡単にするために、ATL を使っています。

    HRESULT SetWindowAppId(WCHAR *pszAppId)
    {
        CComPtr<IPropertyStore> propStore;
        HRESULT hRes = SHGetPropertyStoreForWindow(m_hWnd, IID_PPV_ARGS(&propStore));
        if (SUCCEEDED(hRes))
        {
            CPropVariant propvar;
            InitPropVariantFromString(pszAppId, &propvar);
            hRes = propStore->SetValue(PKEY_AppUserModel_ID, propvar);
            if (FAILED(hRes))
            {
                // エラー
            }
        }
        else
        {
            // エラー
        }
    
        return hRes;
    }

    なお、Application Identity の推奨されるフォーマットは

    CompanyName.ProductName.SubProduct.VersionInformation

    になっています。
    Application Identity をカスタマイズすることによって、Windows 7 に ”より対応” したアプリケーションができると思います。

    参考情報

    Win7: ThinkPad もマルチタッチに

    ノートと言えば、大御所の ThinkPad ですが、こちらも Windows 7 マルチタッチに対応です。

    パネルは静電誘導式で 4 ポイントタッチに対応とのこと。
    他にもたくさん出てきそうなので、この辺でマルチタッチ ハードウェアの追っかけはやめときます。
    各メーカーの秋冬モデルでは、マルチタッチはあって当然な機能になりつつありますね。

    次回からは、このブログ本来の方向に…。