MFC中的NMHDR結構體和NMUPDOWN結構體

2022-07-17 00:39:17 字數 4155 閱讀 4262

建立spin控制項,建立udn_deltapos乙個訊息函式後:

1

void cspindlg::ondeltaposspin1(nmhdr* pnmhdr, lresult*presult)23

問題1:引數nmhdr* pnmhdr, lresult* presult幹嘛用?nmhdr結構體,檢視msdn,經過應用,其意義如下

1 typedef struct

tagnmhdr nmhdr;

id號很好知道,建立的時候就有分配了乙個id,如idc_spin1
通知**,既訊息型別,也可以知道該訊息是udn_deltapos

控制項控制代碼呢,馬上開始想到經常用的cwnd*getdlgitem(intnid),然而該函式返回的是乙個指標物件,並不是控制代碼。

可以用sdk 平台函式:返回是指定控制項的控制代碼

1

hwnd getdlgitem(

2 hwnd hdlg, //

handle of dialog box 對話方塊視窗控制代碼

3int niddlgitem //

identifier of control 控制項標示符,即id

4 );

可以執行下**,驗證是否正確

1

void cspindlg::ondeltaposspin1(nmhdr* pnmhdr, lresult*presult) 211

12   *presult = 0

;13 }

當你點選spin按鈕時,彈出對話方塊,提示spin down,說明是對的。

另一種方式也可以獲取控制項控制代碼

1

if ((pnmhdr->idfrom == idc_spin1) && (pnmhdr->code == udn_deltapos) && (pnmhdr->hwndfrom == getdlgitem(idc_spin1)->m_hwnd/*

hwnd

*/))

2

m_hwnd是屬於cwin的乙個成員,而cwnd*getdlgitem(intnid)const 返回乙個指向cwnd的乙個指標,所以就可以利用改指標來引用m_hwnd成員,從而獲得該控制項的控制代碼。問題2:nm_updown* pnmupdown = (nm_updown*)pnmhdr; 為什麼這樣寫,目的是幹嘛呢?

首先知道nm_updown是nmupdown結構體名的巨集,把pnmhdr強制轉化為該型別,該結構體如下

1 typedef struct

_nm_updown nmupdown, far *lpnmupdown;

在bool cspindlg::oninitdialog()函式中加入下面幾行**,進行初始化

1 cspinbuttonctrl *pspin = (cspinbuttonctrl *)getdlgitem(idc_spin1);2//

pspin->setrange(100, 0);

//按上面的箭頭是減,按下面的箭頭是加

3 pspin->setrange(0, 100); //

按上面的箭頭是加,按下面的箭頭是減

4 pspin->setbase(10); //

按十進位制方式

5 pspin->setpos(8); //

把當前值設定為8

然後在void cspindlg::ondeltaposspin1(nmhdr* pnmhdr, lresult* presult) 加上驗證**

1

void cspindlg::ondeltaposspin1(nmhdr* pnmhdr, lresult*presult) 212

13if ((pnmupdown->hdr.idfrom == idc_spin1)&& (pnmupdown->hdr.code == udn_deltapos) && (pnmupdown->hdr.hwndfrom ==hwnd))

1417

18if (pnmupdown->ipos == 8)19

2223

if(pnmupdown->idelta == 1)24

2728

if(pnmupdown->idelta == -1)29

3233 *presult = 0

;34 }

可以逐步驗證每個成員的意義是否正確,其中寫法1和寫法2是結果是相同的。

問題3:nm_updown* pnmupdown = (nm_updown*)pnmhdr

該函式中的兩個不同型別結構體,經強制轉換賦給另外乙個結構體,最終兩結構體都占用同快記憶體嗎?還有pnmhdr裡的成員會怎麼傳遞呢?

首先看個例1

1 #include 2

using

namespace

std;

34 typedef struct_a5

a;10

11 typedef struct

_b12

b;17

18int main(void)19

輸出結果:

例1中經強制轉換並賦給b後,b和pa指向同塊記憶體,貌似成員值也賦過來了。最後兩行的值由於沒初始化,根據不同系統輸出不確定的值。

在看個例2

1 #include 2

using

namespace

std;

34 typedef struct_a5

a;10

11 typedef struct

_b12

b;17

18int main(void)19

輸出結果:

例2中,在結構體b中的a hdr;成員放置到最後,其輸出結果就有大所不同。

如下簡單示意圖,假設a結構體定義變數後,記憶體分配情況:

記憶體位址        記憶體中的值

0x00002 ->       1

0x00006 ->      10

0x0000c ->      100

經過強制轉換,賦給b後,使b、pa和a三個變數都同時指向同塊記憶體的首位址。結構體變數b分配的記憶體空間在結構

體變數pa的記憶體基礎上繼續分配了0x00010、0x00014兩個位址,故結構體變數b的前三個成員變數值就是1、10、100。

所以不能理解成員變數值傳遞,而是要從記憶體上去理解。成員變數只是乙個代號而已。

還是不理解的話,可以把a中的三個成員變數位址打出來,然後把b中的成員變數位址也打出來對比就知道了。

1 cout<

hwnd位址

"<

"2 cout<

idfrom位址

"<

"3 cout<

code位址

"<

"4...

5 ...

備註:設定增量步長可以使用setaccel(int naccel,udaccel* paccel )函式:

1、引數naccel表示由paccel指定的udaccel結構的數目.

2、paccel指向乙個udaccel結構陣列的指標

如下,步長為2

1

udaccel udaccel;

2 udaccel.ninc = 2; //

步長為2的增或減

3 udaccel.nsec = 0; //

在改變前所等待的秒數

45 spin1->setaccel(1,&udaccel);

C和C 中的結構體

c c 結構體的區別 c中的結構體和c 中結構體的不同之處 在c中的結構體只能自定義資料型別,結構體中不允許有函式,而c 中的結構體可以加入成員函式。c 中的結構體和類的異同 一 相同之處 結構體中可以包含函式 也可以定義public private protected資料成員 定義了結構體之後,可...

Swift中類和結構體

1.類和結構體對比 swift 中類和結構體有很多共同點 與結構體相比,類還有如下的附加功能 2.類和結構體的定義語法 類和結構體有著類似的定義方式。我們通過關鍵字class和struct來分別表示類和結構體,並在一對大括號中定義它們的具體內容,如下 class videomode struct r...

C 的中的結構體和列舉

1 結構體 struct 的使用 使用struct定義乙個結構 struct book book 結構體變數的定義 struct book tmpbook 要訪問結構體變數中的資料 tmpbook.isbn tmpbook.publisher tmpbook.bookname 2 列舉 enum 的...