for(x=0;x<DEVISIONS;x++)
for(y=0;y<DEVISIONS;y++)
hwndChild[x][y]=CreateWindow(szChildClass,NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0,0,0,0,
hwnd,(HMENU) (y << 8 | x),
(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
NULL);
上面代碼對於一般入門者或者是很少接觸過位運算的同志,感覺這句代碼(上面藍色標記部分)真的很難理解,甚至看着頭痛!這是啥子呀?抓腦門……
其實如果分析開來並不難懂:這裏本來參數是“菜單”,但是對於子窗口來說,該參數稱爲“子窗口ID”,是一個用來唯一標識子窗口的數值。
MSDN中有說明:
hMenu [in]
Handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window,hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used.For a child window,hMenu specifies the child-window identifier,an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.
既是說明子窗口ID是一個int類型咯…
這個ID是用戶自己定義滴,但是注意,不要撞車喔,要不然會很悲劇!
那就說明它是4個字節32位咯…(VC++6.0)
好,迴歸正題:
在上面的藍色標識代碼中,其實就是用來定義ID滴(有人吐槽:定義一個ID而已,有必要弄出那麼多個雞巴符號麼?額~~)。
當然,人家有道理的。爲了防止撞車,所以才巧妙的運用了位運算的知識!
(y<<8 | x)其實就是把x和y一起合成子窗口ID的,怎麼合成?
1.y<<8其實就是把低八位向左移,然後低八位都補0。
假如int y = 1;那麼二進制就是 0000 0000 0000 0000 0000 0000 0000 0001;(額……不用算了,就31個0,其實可以省略的,不過爲了突出32位,哎…);
那麼y<<8 就是 0000 0000 0000 0000 0000 00010000 0000;
2.再看 (y<<8 ) | x,
假如 int x = 2;那麼二進制就是0000 0000 0000 0000 0000 0000 0000 0010;
那麼現在就簡單啦:
用y<<8的結果和上面的進行或運算得:0000 0000 0000 0000 0000 0001 0000 0010;
(運算規則請看前面章節,有詳解)。
那麼這樣,就完成了把x和y的組合了,y存在9~16位,x存在1~8位(也不知道是從哪邊開始算,我就大概從右算起吧…哎,學藝不精啊)而且只要x和y的範圍不超過…255吧應該,都不會出現子窗口ID撞車的現象。
而且以後需要x和y的值時,還可以通過位運算得出:
x=idfocus&0xFF;
y=idfocus>>8;
這個簡單了吧?就是上面的逆運算而已。說明一下0xFF是16進制的(感覺在說廢話),也就是(省略24個0)1111 1111
x=idfocus&0xFF;就是取低八位數據賦值給x。其它高位的都是0了。
y=idfocus>>8;就是把9位以後的右移八位,高八位都補0哈。然後賦值給y了。如果是上面的數據,那麼結果就是從
0000 0000 0000 0000 0000 0001 0000 0010到
0000 0000 0000 0000 0000 0000 0000 0001
總結一下:通過巧妙的位運算可以高效率的解決一些問題,可以把若干個數據保存到各個位上面組合,以後可以通過簡單的位運算取出!(又是廢話……別砸~)