Help and Support

文書番号: 937739 - 最終更新日: 2007年5月24日 - リビジョン: 1.2

Windows Mobile 5.0 以降で WideVGA 搭載デバイスでメニューのないマネージド アプリケーション表示中に画面を回転させると表示が崩れる

目次

すべて展開する | すべて折りたたむ

現象

Microsoft Visual C# や Microsoft Visual Basic .NET でメニューのないフォームをもったアプリケーションを WideVGA (800x480 の画面サイズ) 搭載の Microsoft Windows Mobile 5.0 および Windows Mobile 6.0 アプリケーションで動作させたとき、画面を計 4 回ローテーションさせると、画面が表示が崩れる問題が発生します。この問題は Microsoft .NET Compact Framework 2.0 を使用した際に発生します。

原因

この現象は、Wide VGA 対応の Windows Mobile 5.0 以降の オペレーティング システム上で .NET Compact Framework 2.0 によって生成されたオフ スクリーン上にあるメニュー バーのローテーション処理に不具合があるために発生します。

回避策

この現象を回避するためには、ネイティブ コードの C/C++ を使用して、メニュー バーの位置を調整するための DLL を作成し、その DLL でエクスポートした関数を、マネージド コードからプラットフォーム 呼び出し (P/Invoke) を使用して関数をコールします。
  1. 問題の発生しているアプリケーションのソリューションを Visual Studio 2005 で開きます。
  2. 開いたソリューションに対してネイティブ コードの DLL プロジェクトを追加します。Visual Studio 2005 で [ファイル] メニューから、[追加] 、[新しいプロジェクト] の順にクリックします。
  3. [新しいプロジェクトの追加] ウィザードで、以下の設定を行い [OK] をクリックします。
    • プロジェクトの種類 : ツリービューの [Visual C++] 以下にある [スマート デバイス] を選択
    • テンプレート : [Win32 スマートデバイス プロジェクト] を選択
    • プロジェクト名 : 任意の名称を入力
  4. 次に [スマート デバイス デバイス プロジェクト ウィザード ? <プロジェクト名称>] のダイアログが表示されたら以下のような設定にし、[完了] ボタンをクリックします。
    • プラットフォーム : Windows Mobile 5.0 Pocket PC SDK および Windows Mobile 6.0 Professional SDK
    • アプリケーションの設定 : [アプリケーションの種類] は [DLL] にチェック、[追加のオプション] は選択なし
  5. ソリューション エクスプローラ上に、追加した DLL のプロジェクトがあることを確認し、追加した DLL のプロジェクトの C++ ソース ファイル <プロジェクト名>.cpp ファイルをダブルクリックし、Visual Studio 2005 のエディタで開きます。
  6. 開いた .cpp ファイルの末尾に以下のコードを追加します。
    //
    // EnumWindows API 用コールバック関数
    //
    BOOL CALLBACK
    WindowEnumProc(HWND hwnd, LPARAM lParam)
    {
        TCHAR wszClassName[50];
        HWND hwndForm = (HWND)lParam;
    
        //
        // フォームに関連付けられているメニュー バーを見つけ出し
        // その位置をオフスクリーンへと調整します
        //
        if ( (GetClassName(hwnd, wszClassName, 49) != 0) &&
             (_tcscmp(wszClassName, _T("menu_worker")) ==0) )
        {
            if (hwndForm == GetWindow(hwnd, GW_OWNER))
            {
                SetWindowPos(hwnd, NULL, -10000, -10000, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
                return FALSE;
            }
        }
        return TRUE;
    }
    
    //
    // 以下の関数をエクスポートし、マネージド コードから呼び出します
    //
    //  hwndForm - [IN] マネージド アプリケーションのフォームのウィンドウ ハンドル
    //
    extern "C" BOOL __declspec(dllexport)
    AdjustAttachedOffscreenMenu(HWND hwndForm)
    {
        return EnumWindows(WindowEnumProc, (LPARAM)hwndForm);
    }
  7. Visual Studio 2005 の [ファイル] メニューから [<プロジェクト名>.cpp の保存 (S)] をクリックして、変更したファイルを保存します。
  8. 問題の発生しているマネージド アプリケーションのフォームを開きます。 ソリューション エクスプローラでフォームのソース ファイルをダブル クリックします。
  9. フォームのデザイン ビューを右クリックして、[プロパティ] をクリックします。
  10. [イベント] の [表示] にある [Paint] に Paint のハンドラを追加します。
  11. ソリューション エクスプローラでフォームのソース ファイルを右クリックし、 [コードの表示] をクリックしてコードを表示します。
  12. 上記手順 10 で追加した Paint ハンドラに DLL で実装した AdjustAttachedOffscreenMenu 関数を P/Invoke を使用して、呼び出します。

    Paint ハンドラの実装例を以下に示します。

    Visual Basic の場合

    
    Imports System.Runtime.InteropServices
    
    Public Class Form1
        ' P/Invoke
        <DllImport("MyWorkaround.dll")> _
        Private Shared Function AdjustAttachedOffscreenMenu(ByVal hwndForm As IntPtr) As Integer
        End Function
    
        ' 最初の 1 度だけ AdjustAttachedOffscreenMenu を呼び出します
        Private fPainted As Boolean = False
        Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            If fPainted = False Then
                AdjustAttachedOffscreenMenu(Me.Handle)
                fPainted = True
            End If
        End Sub
    
      
    

    C# の場合

    using System.Runtime.InteropServices;
    
    namespace DeviceApplication1
    {
        public partial class Form1 : Form
        {
            [DllImport("MyWorkaround .dll")]
            static extern bool AdjustAttachedOffscreenMenu(IntPtr hwndForm);
    
            // 最初の1 度だけAdjustAttachedOffscreenMenu を呼び出します
            bool fPainted = false;
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                if (!fPainted)
                {
                    fPainted = true;
                    AdjustAttachedOffscreenMenu(this.Handle);
                }
            }
      
    
    

状況

次期 .NET Compact Framework (.NETCF 3.5) で対処される予定です。

詳細

問題の再現手順

  1. ランドスケープ モード (横画面モード) のとき、メニューのない .NET Compact Framework アプリケーションを起動します。
  2. アプリケーション表示中に画面モードを、ポートレイト モード(縦画面モード) 、ランドスケープ モード 、ポートレイト モード、ランドスケープ モード というように最低 4 回画面モードを切り替えます。

結果

アプリケーション ウィンドウのサイズが半分に縮小され表示が崩れます。

この資料は以下の製品について記述したものです。
  • Windows Mobile 5.0 for Pocket PC
  • Windows Mobile 5.0 for Pocket PC Phone Edition
  • Windows Mobile 6
キーワード:?
kbbug kbexpertiseinter kbinfo kbhowto kbtshoot KB937739
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"