◀Unicode版開発トップへ
  • 1322 dlgフォルダの整理
    • 1323 Re: dlgフォルダの整理
      • 1327 Re2: dlgフォルダの整理
        • 1329 Re3: dlgフォルダの整理
          • 1335 Re4: dlgフォルダの整理
            • 1336 Re5: dlgフォルダの整理
              • 1338 Re6: dlgフォルダの整理
                • 1342 Re7: dlgフォルダの整理
                  • 1343 Re8: dlgフォルダの整理
  • [1322] dlgフォルダの整理 Uchi 2010年07月14日 21:25

    dlgフォルダの下のファイルのコモンコントロールの制御をSendMessageから<WindoesX.h>を使用し書き換えました。
    使用していないincludeファイルの削除、
    CDlgAbout の SubclassWindow 関数の名称変更
    等も行っています。

    PatchUnicode#3029491
    • [1323] Re: dlgフォルダの整理 もか 2010年07月14日 23:38

      利点は、
      ・Visual Studio上でマクロの定義がポップアップヘルプ代わりになる
      ・SendMessageで未使用の引数0だったものがなくなり惑わされない
      ・戻り値型がキャスト済みで便利
      とかですかね。
      パッチの内容の範囲では、特に問題はないようです。
      コードの見た目はよくなると思います。
      #VS2005だと CDlgFind.cpp の ::DlgItem_SetText のポップアップがなんかおかしい。なんでだろう

      ----

      ただし私はどちらかというと WindowsX.h 使用禁止にしたいんですがだめですか。
      MSDN にも、載っていたり載っていなかったりして不便で、載っていても結局ウィンドウメッセージを見に行かないといけない。
      (VC6系のヘルプで飛べないので個人的にすごく不便)
      マクロはCスタイルキャストで実装されていて前時代的。
      定義が被っていたりすると怖い。
      さらにSDKのものを見くらべると、ヘッダファイルの内容がたまに間違っていて、あとで修正されてる。
      あと SendMessageAny をわざわざ SendMessage に戻す理由はなんですか?
      いまは、TCHAR混在でAnyかどうか気になることがあります。
      (AnyがAnycastみたいだというのはマイナスポイント)

      参考にcommctrlのほうのコードですがどうおもいますか?
      これ、警告レベルを上げても警告なしにコンパイルできるとおいます。
      #include <windows.h>
      #include <commctrl.h>

      HWND hwnd = NULL;
      int i = 2;
      RECT itemRect;
      CHAR* testA = NULL;
      TabCtrl_GetItemRect( hwnd, i, &itemRect );
      TabCtrl_GetItemRect( hwnd, i, testA );
      TabCtrl_GetItemRect( hwnd, &itemRect, i );
      const int countMacro = TabCtrl_GetItemCount( hwnd );

      ::SendMessage( hwnd, TCM_GETITEMRECT, i, (LPARAM)&itemRect );
      ::SendMessage( hwnd, TCM_GETITEMRECT, (LPARAM)&itemRect, (WPARAM)i );
      const int countApi = ::SendMessage( hwnd, TCM_GETITEMRECT, 0, 0 );

      もちろん、SendMessageは HWND UINT WPARAM LPARAM です。
      SendMessage + キャストだと「ん?危ないかも」と思えます。
      マクロだと臭いものにフタをしただけで、K&Rとかベーシックみたいな危うさを感じます。
      ApiWrap は すばらしいと思うのだけど using namespace されていて、
      普通のマクロと見た目が完全に同じだから、どれがAipWrapか名前を覚えるまで、エディタ上とかsvnの差分表示だとコードを読むときの効率が悪いなぁと。
      • [1327] Re2: dlgフォルダの整理 Uchi 2010年07月15日 20:38

        もかさん、コメントありがとうございます。

        >#VS2005だと CDlgFind.cpp の ::DlgItem_SetText のポップアップがなんかおかしい。なんでだろう
        私の環境では、最初表示されるまで、20秒ぐらいかかりました。2回目からはすぐ出ましたが。
        最初のポップアップはかなり時間がかかることがあるようです。

        >ただし私はどちらかというと WindowsX.h 使用禁止にしたいんですがだめですか。
        >MSDN にも、載っていたり載っていなかったりして不便で、載っていても結局ウィンドウメッセージを見に行かないといけない。
        >(VC6系のヘルプで飛べないので個人的にすごく不便)
        ローカルのMSDNは最近使用していないのでよくわかりませんが、
        Web上のMSDNでは去年あたりから SendMessage のパラメータのページが順次消されている様です。
        ローカルのMSDNを使用していない私としては、WindowsX.h を使用したほうが分かりやすいので修正しました。

        >マクロはCスタイルキャストで実装されていて前時代的。
        ラッパを作成していただけるのであれば、そちらのほうを使用することは吝かではないのですが、
        そこまで必要あるか、WindowsX.h で充分だろう というのが私の考えです。
        キャストに関してはSendMessage直と同程度の危険性と認識しています。

        >定義が被っていたりすると怖い。
        CDlgAboutでかぶっていましたね。

        >さらにSDKのものを見くらべると、ヘッダファイルの内容がたまに間違っていて、あとで修正されてる。
        ちょっと怖いですね。確認してみましょう。

        >あと SendMessageAny をわざわざ SendMessage に戻す理由はなんですか?
        1. SendMessageAny が SendMessage の単なるマクロであること。
        つまり何の機能も果たしていないこと。
        2. StdApi.h noの定義箇所に
        // 過去のUNICODE化の名残です。
        // 現在となっては、特に意味はありません。
        とある(つまりのの遺産)。
        3. 現在のソースで、SendMessageAny,SendMessageCmd,SendMessageがごちゃまぜで使われている。
        という状態と認識し、特に3.の修正をかけたいという事です。
        • [1329] Re3: dlgフォルダの整理 もか 2010年07月16日 02:09

          >タイトル: Re3: dlgフォルダの整理
          >発言者: Uchi
          >もかさん、コメントありがとうございます。
          >
          >>#VS2005だと CDlgFind.cpp の ::DlgItem_SetText のポップアップがなんかおかしい。なんでだろう
          >私の環境では、最初表示されるまで、20秒ぐらいかかりました。2回目からはすぐ出ましたが。
          >最初のポップアップはかなり時間がかかることがあるようです。
          >
          >>ただし私はどちらかというと WindowsX.h 使用禁止にしたいんですがだめですか。
          >>MSDN にも、載っていたり載っていなかったりして不便で、載っていても結局ウィンドウメッセージを見に行かないといけない。
          >>(VC6系のヘルプで飛べないので個人的にすごく不便)
          >ローカルのMSDNは最近使用していないのでよくわかりませんが、
          >Web上のMSDNでは去年あたりから SendMessage のパラメータのページが順次消されている様です。
          たとえばどのメッセージとかないんでしょうか。
          VC2005EEで、F1+ウェブも探す設定にしても、前から見つからないという表示しか出ません。。。
          PSDKのヘルプとの連携も分からないです。VC2008 EEのF1キーでの検索もうまくいきません。
          IE6が悪いのか色々入ってるのが悪いのか判断付かないんですが、使い物にならないので。

          >>マクロはCスタイルキャストで実装されていて前時代的。
          >ラッパを作成していただけるのであれば、そちらのほうを使用することは吝かではないのですが、
          >そこまで必要あるか、WindowsX.h で充分だろう というのが私の考えです。
          >キャストに関してはSendMessage直と同程度の危険性と認識しています。
          私は、Cスタイルキャストマクロは、SendMessageの何倍も有害だとおもってます。
          >>定義が被っていたりすると怖い。
          >CDlgAboutでかぶっていましたね。
          MFCでも被っていて、マクロをundefしろとKBに書かれています。

          >>あと SendMessageAny をわざわざ SendMessage に戻す理由はなんですか?
          >1. SendMessageAny が SendMessage の単なるマクロであること。
          > つまり何の機能も果たしていないこと。
          >2. StdApi.h noの定義箇所に
          > // 過去のUNICODE化の名残です。
          > // 現在となっては、特に意味はありません。
          >とある(つまりのの遺産)。
          >3. 現在のソースで、SendMessageAny,SendMessageCmd,SendMessageがごちゃまぜで使われている。
          >という状態と認識し、特に3.の修正をかけたいという事です。
          • [1335] Re4: dlgフォルダの整理 Uchi 2010年07月17日 19:27

            >>>ただし私はどちらかというと WindowsX.h 使用禁止にしたいんですがだめですか。
            >>>MSDN にも、載っていたり載っていなかったりして不便で、載っていても結局ウィンドウメッセージを見に行かないといけない。
            >>>(VC6系のヘルプで飛べないので個人的にすごく不便)
            >>ローカルのMSDNは最近使用していないのでよくわかりませんが、
            >>Web上のMSDNでは去年あたりから SendMessage のパラメータのページが順次消されている様です。
            >たとえばどのメッセージとかないんでしょうか。
            >VC2005EEで、F1+ウェブも探す設定にしても、前から見つからないという表示しか出ません。。。
            >PSDKのヘルプとの連携も分からないです。VC2008 EEのF1キーでの検索もうまくいきません。
            >IE6が悪いのか色々入ってるのが悪いのか判断付かないんですが、使い物にならないので。
            私は、Webブラウザ(Operaが主で、IE8、FFも使用)でhttp://msdn.microsoft.com/の中の検索を(昨年までは)使用していました。
            MSは、昨年あたりからWebサイトをリニューアルしているようで、 SendMessage のパラメータ(CB_SHOWDROPDOWN等)のページを消している様です。
            昨年まではヒットしていました。

            >>>マクロはCスタイルキャストで実装されていて前時代的。
            >>ラッパを作成していただけるのであれば、そちらのほうを使用することは吝かではないのですが、
            >>そこまで必要あるか、WindowsX.h で充分だろう というのが私の考えです。
            >>キャストに関してはSendMessage直と同程度の危険性と認識しています。
            >私は、Cスタイルキャストマクロは、SendMessageの何倍も有害だとおもってます。
            どのようにでしょうか?

            >>>定義が被っていたりすると怖い。
            >>CDlgAboutでかぶっていましたね。
            >MFCでも被っていて、マクロをundefしろとKBに書かれています。
            MFCを使用しているのならば、WindowsX.hを使用する意味はないわけです(同党の機能がMFC内にあるので)。
            そして、サクラエディタではMFCを使用していないのでWindowsX.hを使用しても問題ないはずですが、如何でしょう。
            • [1336] Re5: dlgフォルダの整理 もか 2010年07月18日 01:54

              >>>キャストに関してはSendMessage直と同程度の危険性と認識しています。
              >>私は、Cスタイルキャストマクロは、SendMessageの何倍も有害だとおもってます。
              >どのようにでしょうか?
              長い説明も書き終えているけどそれはやめて、
              ・アプリケーションハンガリアン
              ・C++の新しいキャストの必要性
              と同じ理由です。おかしいものは可能ならエラーにする。
              無理なら「コードを見たときに」そのコードが正しくないように見えなければならない。
              Unicode版は、ベターC + classの旧コードとは違って、積極的にタイプセーフを使う方針に見えますが違いますか。
              これは、最初の返信で書いたコード例の通り。
              もう、C言語の亡霊にびくびくしながら、関数(に見える何か)を確認して回るのはイヤ。
              どっちも結局キャストしているから同じと思っているのでしょうか。
              SendMessageなら、(LPARAM)とか(*TCHAR)などがついていて、キャストが目に見えています。
              だから、SendMessageの引数が合っているか不安になります。不安でいいんです。危険だから。
              マクロでは、キャストがコード上に現れないので、引数が違っていても、人もコンパイラも気が付かなくて、見過ごす確率が高くなります。
              ListBox_SetCurSelがSendMessageと同列の危険性を内包しているのを理解しているベテランWin32/C開発者は尊敬しますが、私はそうではないです。

              ・windowsxではないけど、CommCtrl.hのRect関連は 引数に副作用があると正常に使えないかも(min/maxと同じ)
              ListView_GetItemRect(hwnd, i, pRect++, LVIR_LABEL);
              pRectは3回インクリメントされる。
              私は怖いので引数でインクリメントはしませんが、引数部分に関数を指定したり、一時インスタンスが生成されていると悲惨なことに。
              >ラッパを作成していただけるのであれば
              そのうちやるつもりではありましたが、もうやらないかも。
              >1. SendMessageAny が SendMessage の単なるマクロであること。
              > つまり何の機能も果たしていないこと。
              Anyになっていれば、A/Wで引数型が同じで考慮しなくていいことを人間が読み取れる
              (ただし一部おかしいきがする)
              windowsxマクロでは無理

              >2. StdApi.h noの定義箇所に
              > // 過去のUNICODE化の名残です。
              > // 現在となっては、特に意味はありません。
              >とある(つまりのの遺産)。
              当然そのコメントは読んでいます。それはフルWCHAR化してANSIビルドを使わない頃のコメントだったりしませんか。
              もうTCHAR部分はいますぐ捨てる。というなら別にいい。

              >CB_SHOWDROPDOWN
              http://msdn.microsoft.com/en-us/library/bb775919%28v=VS.85%29.aspx
              各コントロールの一覧
              http://msdn.microsoft.com/en-us/library/bb773169(v=VS.85).aspx

              結局目視でのチェックが必要なら、
              /(ListBos_|Button_|ComboBox_|Edit_|ListV
              iew_|ScrollBar_|Static_|TabCtrl_)|(Messa
              ge)|printf/
              とか、なんか並べるて確認するより、
              /(Message|printf/
              で確認した方が、漏れも少ないし簡単。一括チェックでも脳内チェックでもです。

              ほんとうは、説明を書いている時間でコードを書き終えられそうなんだけど、まあいいや。
              • [1338] Re6: dlgフォルダの整理 もか 2010年07月18日 14:10

                自分で説明しようとするからフレームの元であることに気が付いた。

                間違ったコードは間違って見えるようにする
                http://www.joelonsoftware.com/articles/Wrong.html
                日本語訳(英語の方は読んでない):
                http://local.joelonsoftware.com/mediawiki/index.php/%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E3
                %82%B3%E3%83%BC%E3%83%89%E3%81%AF%E9%96%
                93%E9%81%95%E3%81%A3%E3%81%A6%E8%A6%8B%E
                3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81
                %AB%E3%81%99%E3%82%8B
                「C++の設計と進化」もおすすめです。
                ただしもしNULLは0と書けという話があったら、今はnullptrがおすすめ。nullptrがなければNULLがおすすめ(Googleが推奨)
                http://www.textdrop.net/google-styleguide-ja/cppguide.xml

                私からはwindowsx利用に関しては3種類の修正案を提示しておきます。
                A. windowsx.h の中で使えるものを決めておく。それ以外は使わない。
                windowx.h すべてがだめだとはさすがに思わないから
                >・SendMessageで未使用の引数0だったものがなくなり惑わされない
                >・戻り値型がキャスト済みで便利
                などに該当するものを使えるようにする。
                (Uchiさんのパッチの部分はほとんどそうだと思う)
                だたし決めても、今後リストにないマクロが新規コードで使用されていないかチェックが必要。
                使用不可マクロはすべてundefする
                例えば int ListBox_GetCurSel(HWND); は有用
                ListBox_AddString は undef。ApiWrap::List_AddStringを使う
                ApiWrapは 紛らわしさ解消のため using namespaceをやめる。
                ListBox_SetCurSel(HWND, int)をどうするかが議論の対象になる。

                B. 文字列関連はAipWrapに。それ以外はSendMessageAnyに。windowsx.hは封印
                (int)SendMessage(hwnd, LB_GETCURSEL, 0 ,0 ); は
                B.のオプション案
                (int)SendMessageAny(hwnd, LB_GETCURSEL, NOT_USE_0 ,NOT_USE_0 ); とかにしておくとか。
                NOT_USE_0は適当に定義かどこかに代用品ないかな。0でいいなら0のまま。

                C. ほしいのは全部ラップ関数を書く
                ラップがほしいのはラップへ。
                別にSendMessageでいいや。とおもうならSendMessageAnyに。
                SendMessageのままのものは、修正対象

                残ったPostMessageはPostMessageAny と新設の PostMessageTchar(仮名) とかにする
                • [1342] Re7: dlgフォルダの整理 Uchi 2010年07月21日 00:08

                  もかさんの好みに合わせたと思う修正をしたものをアップしました

                  • [1343] Re8: dlgフォルダの整理 もか 2010年07月21日 01:30

                    なにこれ、すごい。ありがとうございます。
                    さっそく見てみます。目視チェックをかけるので、しばしお待ちを。

                    なにかヘッダ周りの確認はコツがあるのかな。それともツールとかあるんでしょうか。