ビット演算

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
みそ油

ビット演算

#1

投稿記事 by みそ油 » 8年前

Win32APIを利用したプログラムのソースコードについての質問です。

コード:

/* ソースコード1 旧タイプのツールバーに変更 */
style = GetWindowLongPtr(hTool, GWL_STYLE);
style = style & ~TBSTYLE_FLAT & ~TBSTYLE_TRANSPARENT;    /* ? */
SetWindowLongPtr(hTool, GWL_STYLE, style);

コード:

/* ソースコード2 フラットタイプのツールバーに変更 */
style = GetWindowLongPtr(hTool, GWL_STYLE);
style = (style | TBSTYLE_FLAT) & ~TBSTYLE_TRANSPARENT;    /* ? */
SetWindowLongPtr(hTool, GWL_STYLE, style);

コード:

/* ソースコード3 透明タイプのツールバーに変更 */
style = GetWindowLongPtr(hTool, GWL_STYLE);
style = style | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT;    /* ? */
SetWindowLongPtr(hTool, GWL_STYLE, style);

コード:

/* 変数の詳細 */
LONG style;
HWND hTool;    /* ツールバーのハンドル */
ソースコード1では、style = TBSTYLE_OLD にしたいのに、/* ? */ の処理だと style = 0 になりますよね。
ソースコード2や、ソースコード3でも、style は望んでいる値にはならないと思います。
/* ? */ の行のコードはどのような意味を持つのでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ビット演算

#2

投稿記事 by みけCAT » 8年前

みそ油 さんが書きました:ソースコード1では、style = TBSTYLE_OLD にしたいのに、/* ? */ の処理だと style = 0 になりますよね。
0になるかはもとのstyleの値によります。
みそ油 さんが書きました:ソースコード2や、ソースコード3でも、style は望んでいる値にはならないと思います。
なぜですか?
思うだけでなく、実験はしましたか?
みそ油 さんが書きました:/* ? */ の行のコードはどのような意味を持つのでしょうか。

コード:

/* ソースコード1 旧タイプのツールバーに変更 */
/* styleのTBSTYLE_FLATフラグとTBSTYLE_TRANSPARENTフラグを折る */
style = style & ~TBSTYLE_FLAT & ~TBSTYLE_TRANSPARENT;    /* ? */

/* ソースコード2 フラットタイプのツールバーに変更 */
/* styleのTBSTYLE_FLATフラグを立てたあと、TBSTYLE_TRANSPARENTフラグを折る */
style = (style | TBSTYLE_FLAT) & ~TBSTYLE_TRANSPARENT;    /* ? */

/* ソースコード3 透明タイプのツールバーに変更 */
/* styleのTBSTYLE_FLATフラグとTBSTYLE_TRANSPARENTフラグを立てる */
style = style | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT;    /* ? */
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

みそ油

Re: ビット演算

#3

投稿記事 by みそ油 » 8年前

>みけCAT さん
回答ありがとうございます。
実験はしたのですが、そのことについては本文では触れていませんでしたね。失礼しました。

まず、ソースコード1についてですが、旧タイプのツールバーに変更ということは、style == TBSTYLE_FLAT あるいは style == TBSTYLE_TRANSPARENT になっているはずです。
ということは、TBSTYLE_FLATの否定とTBSTYLE_TRANSPARENTの否定との論理積であるので、必ず style == 0 になります。

ソースコード2と3については、TBSTYLE_OLD と TBSTYLE_FLAT と TBSTYLE_TRANSPARENT の値を次のように仮定します(各値は2進数とします)。

コード:

/* 各値の仮定をC言語風に書いたもの */
#define TBSTYLE_OLD 00011
#define TBSTYLE_FLAT 00101
#define TBSTYLE_TRANSPARENT 01011
<コード2の場合>
(i)style == TBSTYLE_OLD のとき
最終的な style の値 00100 → 望む値 TBSTYLE_FLAT とは異なる

(ii)style == TBSTYLE_TRANSPARENT のとき
最終的な style の値 00000 → 望む値 TBSTYLE_FLAT とは異なる

<コード3の場合>
(i)style == TBSTYLE_OLD のとき
最終的な style の値 00001 → 望む値 TBSTYLE_TRANSPARENT とは異なる

(ii)style == TBSTYLE_FLAT のとき
最終的な style の値 00001 → 望む値 TBSTYLE_TRANSPARENT とは異なる

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ビット演算

#4

投稿記事 by h2so5 » 8年前

ヘッダを見たり実行してみればわかることなのに、なぜすべて仮定で話を進めているのですか?
本当に実験したならそんな定数値の仮定は出てこないはずです。

みそ油

Re: ビット演算

#5

投稿記事 by みそ油 » 8年前

>h2so5 さん

回答ありがとうございます。
windows.h を参照したのですが、その中で他のヘッダファイルがいくつもインクルードされており、どのヘッダファイルに TBSTYLE_OLD などの値が定義されているのかがわかりませんでしたので、仮定で話を進めさせていただきました。
どちらのヘッダファイルに、TBSTYLE_OLD などの値が定義されているのでしょうか。

みそ油

Re: ビット演算

#6

投稿記事 by みそ油 » 8年前

書き忘れていましたが、プログラムを実行したところ、正常に動作しました。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ビット演算

#7

投稿記事 by h2so5 » 8年前

VisualStudioを使っているなら右クリックで「定義へ移動」を使えばその場所へジャンプできます。
そうでなくても、ブレークポイントを使うとか結果を出力するようにすればわかります。

みそ油

Re: ビット演算

#8

投稿記事 by みそ油 » 8年前

ビット演算子にフラグとしての使い方があったのですね。
/* ? */ 部分のコードのもつ意味については解決しました。
しかし、新たな疑問が生まれました。
GetWindowLongPtr 関数で現在のスタイルを取得して style に代入し、style をいじってSetWindowLongPtr 関数に渡していますが、わざわざそのようなまわりくどいことをする必要があるのでしょうか。
直接 SetWindowLongPtr 関数でスタイルを指定してもいいのではないかな、と思ったのですが、そうすると何か問題があるのでしょうか。

みそ油

Re: ビット演算

#9

投稿記事 by みそ油 » 8年前

TBSTYLE_OLD というマクロが定義されているわけではなかったのですね。自己解決しました。
ありがとうございました。

みそ油

Re: ビット演算

#10

投稿記事 by みそ油 » 8年前

「解決」にするのを忘れていました。失礼しました。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ビット演算

#11

投稿記事 by みけCAT » 8年前

みそ油 さんが書きました:2と3については、TBSTYLE_OLD と TBSTYLE_FLAT と TBSTYLE_TRANSPARENT の値を次のように仮定します(各値は2進数とします)。

コード:

/* 各値の仮定をC言語風に書いたもの */
#define TBSTYLE_OLD 00011
#define TBSTYLE_FLAT 00101
#define TBSTYLE_TRANSPARENT 01011
この仮定のもと、
みそ油 さんが書きました:<コード2の場合>
(i)style == TBSTYLE_OLD のとき
最終的な style の値 00100 → 望む値 TBSTYLE_FLAT とは異なる

(ii)style == TBSTYLE_TRANSPARENT のとき
最終的な style の値 00000 → 望む値 TBSTYLE_FLAT とは異なる
どちらも00100になるはずです。
みそ油 さんが書きました:<コード3の場合>
(i)style == TBSTYLE_OLD のとき
最終的な style の値 00001 → 望む値 TBSTYLE_TRANSPARENT とは異なる

(ii)style == TBSTYLE_FLAT のとき
最終的な style の値 00001 → 望む値 TBSTYLE_TRANSPARENT とは異なる
どちらも01111になるはずです。
みそ油 さんが書きました:しかし、新たな疑問が生まれました。
GetWindowLongPtr 関数で現在のスタイルを取得して style に代入し、style をいじってSetWindowLongPtr 関数に渡していますが、わざわざそのようなまわりくどいことをする必要があるのでしょうか。
直接 SetWindowLongPtr 関数でスタイルを指定してもいいのではないかな、と思ったのですが、そうすると何か問題があるのでしょうか。
直接SetWindowLongPtr 関数でスタイルを指定してしまうと、元から指定されているスタイルが消えて不都合が生じることがあるからでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ビット演算

#12

投稿記事 by みけCAT » 8年前

みそ油 さんが書きました:windows.h を参照したのですが、その中で他のヘッダファイルがいくつもインクルードされており、どのヘッダファイルに TBSTYLE_OLD などの値が定義されているのかがわかりませんでしたので、仮定で話を進めさせていただきました。
どちらのヘッダファイルに、TBSTYLE_OLD などの値が定義されているのでしょうか。
ヘッダファイルがあるディレクトリで、

コード:

grep -r TBSTYLE_FLAT *.h
のようにして検索するといいでしょう。
※正確なオプションは未検証です

Windowsでgrepが入っていなければこれをどうぞ。
Grep for Windows
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る