SetWindowLong And GetWindowLong

通过setwindowlong设置的windows窗口样式总结 对于windows api中创建的窗口,可以通过SetWindowLong函数修改其样式。 函数声明为: LONG SetWindowLongA( HWND hWnd, int nIndex, LONG dwNewLong ); 第二个参数nIndex表示样式的类别,最常见的两个取值为GWL_EXSTYLE (扩展样式)和 GWL_STYLE(样式),分别包括: PS:怕有... 阅读详情

 

SetWindowLong的使用及其简单,比如我们将m_hEdWord窗口的消息处理函数置换为CtrlProc: 

    SetWindowLong(m_hEdWord,GWL_WNDPROC,(DWORD)CtrlProc);


    就这么简单,现在只要m_hEdWord窗口收到消息,那么就会自动调用预先定义的CtrlProc.
  
    有设置,自然也有获取,不过这次我们是通过GetWindowLong函数:

    m_pPreProcEdWord = (WNDPROC)GetWindowLong(m_hEdWord,GWL_WNDPROC);


   现在m_pPreProcEdWord存储的就是目前m_hEdWord的消息处理函数地址.不过,其实通过SetWindowLong函数也能获取消息函数地址:

    m_pPreProcEdWord = SetWindowLong(m_hEdWord,GWL_WNDPROC,(DWORD)CtrlProc);


    不过这时候获取的却是在设置CtrlProc消息处理函数之前的函数地址.也就是说,这两段代码中m_pPreProcEdWord等价:

    1).
    m_pPreProcEdWord = SetWindowLong(m_hEdWord,GWL_WNDPROC,(DWORD)CtrlProc);
    
    2).
    m_pPreProcEdWord = (WNDPROC)GetWindowLong(m_hEdWord,GWL_WNDPROC);
    SetWindowLong(m_hEdWord,GWL_WNDPROC,(DWORD)CtrlProc);


    如果需要调用m_pPreProcEdWord指向的函数,则需要用上CallWindowProc:

    CallWindowProc(m_pPreProcEdWord,hWnd,wMsg,wParam,lParam);
接管Windows Control消息
 
    说了一大堆似乎很有哲理的话,现在就让我们来看看有什么实际的作用吧.
    
    估计这个函数用得最多是在Windows Control中.比如,你想在Edit Box输入某个字符时做一些特殊处理,只能通过SetWindowLong来置换内部的处理函数进而调用自己的特殊处理函数.
    
    我们来举一个非常简单的例子,首先创建一个Edit Box控件,如果在该控件中按下键盘的"ESC",则会退出应用程序.为了方便突出问题的重点,我们的CMainWnd窗口继承于CWndBase(关于CWndBase请见:http://blog.csdn.net/norains/archive/2007/11/10/1878218.aspx)

#pragma once
#include "wndbase.h"

class CMainWnd :
    public CWndBase
{
public:
    CMainWnd(void);
    ~CMainWnd(void);
    BOOL Create(HINSTANCE hInst, HWND hWndParent, const TCHAR *pcszWndClass, const TCHAR *pcszWndName);

protected:    
    static LRESULT CtrlProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

private:
    HWND m_hEdWord; //The window is for inputing the word
    WNDPROC m_pPreProcEdWord; //Pointer to the previous window procedure for the input word window.
};



#include "stdafx.h"
#include "MainWnd.h"

//---------------------------------------------------------------------------------------
//Default value
#define IDC_EDIT_WORD        101


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMainWnd::CMainWnd(void)
{
}

CMainWnd::~CMainWnd(void)
{
}


//----------------------------------------------------------------------
//Description:
//    Create the window. It's override function
//
//----------------------------------------------------------------------
BOOL CMainWnd::Create(HINSTANCE hInst, HWND hWndParent, const TCHAR *pcszWndClass, const TCHAR *pcszWndName)
{
    if(CWndBase::Create(hInst, hWndParent, pcszWndClass, pcszWndName) == FALSE)
    {
        return FALSE;
    }

    //The edit window for input the word
    m_hEdWord = CreateWindowEx(WS_EX_TOPMOST,
                                TEXT("EDIT"),
                                TEXT(""),
                                ES_LEFT  | WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER,
                                GetSystemMetrics(SM_CXSCREEN) / 3,
                                GetSystemMetrics(SM_CYSCREEN) / 3,
                                GetSystemMetrics(SM_CXSCREEN) / 3,
                                GetSystemMetrics(SM_CYSCREEN) / 3,
                                m_hWnd,
                                (HMENU)IDC_EDIT_WORD,
                                m_hInst,
                                NULL);

    //Store the pointer in the window
    SetWindowLong(m_hEdWord, GWL_USERDATA, (DWORD)this);
    //Get the previous window procedure 
    m_pPreProcEdWord = (WNDPROC)GetWindowLong(m_hEdWord,GWL_WNDPROC);
    //Set the new window procedure
    SetWindowLong(m_hEdWord,GWL_WNDPROC,(DWORD)CtrlProc);

    return TRUE;
}


//----------------------------------------------------------------------
//Description:
//    Windows control process.
//
//----------------------------------------------------------------------
LRESULT CMainWnd::CtrlProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
    CMainWnd *pObject = (CMainWnd *)GetWindowLong(hWnd,GWL_USERDATA);

    if(pObject->m_hEdWord == hWnd)
    {
        switch(wMsg)
        {
            case WM_CHAR:
            {
                if((TCHAR) wParam == VK_ESCAPE)
                {
                    PostQuitMessage(0x00);
                }
                break;
            }
        }
        return CallWindowProc(pObject->m_pPreProcEdWord,hWnd,wMsg,wParam,lParam);
    }

    
    //It should never get here !
    return DefWindowProc(hWnd,wMsg,wParam,lParam);
}


    程序代码段很短,但有几点需要注意的地方.
    
    CtrlProc是我们用来置换原有过程的消息处理函数,因为CtrlProc为静态才能回调,而静态函数无法调用成员变量,所以我们在创建Edit Box实例之后在GWL_USERDATA地址存储了当前对象指针:

    SetWindowLong(m_hEdWord, GWL_USERDATA, (DWORD)this);

    然后在CtrlProc函数中获取存储在GWL_USERDATA中的对象指针,用该指针调用成员变量及函数:

    CMainWnd *pObject = (CMainWnd *)GetWindowLong(hWnd,GWL_USERDATA);

    因为我们只是处理WM_CHAR消息,其它消息都采用默认处理方式,所以直接返回调用先前的消息函数:

 return CallWindowProc(pObject->m_pPreProcEdWord,hWnd,wMsg,wParam,lParam);

   这个例子很简单,该工程可以在此下载:http://download.csdn.net/source/324833


3.系统必崩溃代码

    如果将消息处理函数处理转移到已经释放的内存上,那么会有什么结果呢?结果就是,系统崩溃!有兴趣的朋友可以试试这段代码:

LRESULT MyProc(HWND hWnd, UINT wMsg,WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hWnd,wMsg,wParam,lParam);
}

int WINAPI WinMain(    HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR    lpCmdLine,
                    int       nCmdShow)
{
     // TODO: Place code here.

    HWND hWnd = GetForegroundWindow();
    SetWindowLong(hWnd,GWL_WNDPROC,(DWORD)MyProc);
    return 0;
}

 

SetWindowLong设置窗口新过程 函数原型:LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong); 主要说明函数的第二个参数为GWL_WNDPROC的情况。 GWL_WNDPROC Sets a new address for the window procedure. You cannot change this attribute ... 阅读详情

相关推荐

SetWindowLong和SetWindowPos函数详解

一个应用程序可以一个系统美为于类,但是不能以一个其他进程产生的窗口类为子类,SetwindowLong函数通过改变与一个特殊的窗口类相联系的窗口过程来创建窗口子类,从而使系统调用新的窗口过程而不是以前定义的窗口过程。Windows CE:如果这是一个可见的顶层窗口,并且未指定SWP_NOACTIVATE标志,则这个函数将激活窗口、如果这是当前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW标志,则激活另外一个可见的顶层窗口。SWP_NOACTIVATE:不激活窗口。

m0_37346206的博客 4389

SetWindowLong 用法总结

SetWindowLong 函数原型为:LONG SetWindowLong(HWND hwnd,int nIndex,Long dwNewLong);详见MSDN。下面简单总结一下SetWindowLong函数几种常用的地方:1.设置窗口风格   如:SetWindowLong(hWnd, GWL_STYLE, WS_POPUP|WS_BORDER);      //有边框的弹出窗口         SetWindowLong(hWnd, GWL_EXSTYLE,  WS_EX_TOOLWINDOW); 

firehood的专栏 2万+

GetWindowLong说明及应用

“窗口类的封装,从全局窗口消息处理到窗口对象消息处理的映射方法:  对界面进行封装,一般都是一个窗口一个类,比如实现一个最基本的窗口类CMyWnd,你一定会把窗口过程作为这个类的成员函数,但是使用WINAPI创建窗口时必须注册类WNDCLASS,里面有个成员数据lpfnWndProc需要WNDPROC的函数指针,一般想法就是把窗口类的消息处理函数指针传过去,但是类成员函数除非是静态的,否则

cigogo的专栏 5910

GetWindowLong() 和 SetWindowLong()

GetWindowLong()和SetWindowLong()的用法   SetWindowLong  函数功能:该函数改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。  函数原型:LONG SetWindowLon

bpy的专栏 1万+

[WINDOWS开发]消息拦截GetWindowLongSetWindowLong的使用

windows客户端开发,最烦就是句柄了,有了句柄,其他人就可以向你发消息。 所以这个时候,需要使用下GetWindowLong。 1 GetWindowLong是一个Windows API函数。该函数获得指定窗口的有关信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。 LONG GetWindowLong(HWND hWnd,int...

aisin1231的博客 913

windows窗口API函数GetWindowLong\SetWindowLong\SetParent\GetClientRect\SetWindowPos

LONG GetWindowLong( HWND hWnd,int nIndex ) 参数: hWnd:指定窗口的句柄 nIndex:需要获得的信息的类型 值 功能 nIndex取值如下: GWL_EXSTYLE 得到扩展的窗口风格 GWL_STYLE 得到窗口风格 GWL_WNDPROC 得到窗口回调函数的地址,或者句柄。得到后必须使用CallWindowProc函数来调用 GWL_HINSTANCE 得到应用程序运行实例的句柄 GWL_HWND...

weixin_45682858的博客 2180

GetWindowLongSetWindowLong

      函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。   函数原型:LONG GetWindowLong(HWND hWnd,int nlndex);   参数:   hWnd:窗口句柄及间接给出的窗口所属的窗口类。   nlndex:指定要检索的基于0的偏移量。有效值的范围从0到窗口额外内存空间的字节数,减去4。例如,若指定了12位或多于12位的窗体类的额外存储空间,则应设为第三个32位整数的索引位8(12- 4=8)。要获得任意其他值,指定下列值

自由人生 5347

SetWindowLong GetWindowLong SetClassLong GetClassLong

<br />GetWindowLong() SetWindowLong() 详解<br />这两个函数在windows程序中有着重要的作用,依照MSDN说明以下这两个函数。<br />/*****************************************************************/<br />GetWindowLong<br />这个函数可以通过一个窗口的句柄来得到窗口的一些其他的信息,比如ID等<br />语法:<br />LONG GetWindowLong( HWN

liushizhe1987的专栏 1279

GetWindowLongSetWindowLong 详解

函数原型:     LONG GetWindowLong(         HWND hWnd,       // 指定窗体句柄         int nIndex               // 需要获取的信息类型         ); 功能:   该函数获取指定窗体的信息   nIndex值的描述:  GWL_EXSTYLE

fulminate的专栏 1577

GetWindowLong SetWindowLong 详解

GetWindowLong  函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。  函数原型:LONG GetWindowLong(HWND hWnd,int nlndex);  参数:  hWnd:窗口句柄及间接给出的窗口所属的窗口类。  nlndex:指定要检索的基于0的的偏移量。有效值的范围从0到窗口额外内存空间的字节数,减去4。例如,若指

awenC++ 1494

GetWindowLong

函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值。 函数原型:LONG GetWindowLong(HWND hWnd,int nlndex); 参数: hWnd:窗口句柄及间接给出的窗口所属的窗口类。 nlndex:指定要获得值的大于等于0的值的偏移量。有效值的范围从0到额外窗口内存空间的字节数一4例如,若...

dkopg24406的专栏 757

SetWindowLong函数 GetWindowLong函数

<br />这两个函数的具体应用如下: SetWindowLong函数 GetWindowLong函数<br /> <br />Delphi 窗口化游戏 <br />var<br />Thwnd:HWND;//声明变量 句柄变量<br />devmode1:DEVMODE;//屏幕分辨率变量<br />style,exstyle:longint;//窗口属性变量<br />begin<br />//得到游戏句柄<br />Thwnd:=findwindow('CLIENT',nil);<br />//设置分

期待下集是个可爱梦儿 1174

C++ SetWindowLong/GetWindowLong/SetWindowPos

SetWindowLong  函数功能:该函数改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。   函数原型:LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong);   参数:   hWnd:窗口句柄及间接给出的窗口所属的类。   nlndex:指定将设定的大于等于0的偏移值。有效值的范围从0

IT Tech 3037

CallWindowProc与setwindowlong用法

该函数CallWindowProc将消息信息传送给指定的窗口过程。 函数原型: LRESULT CallWindowProc(WNDPROC lpPrevWndFunc,HWND hWnd.UINT Msg,WPARAM wParam,LPARAMIParam); 参数: lpPrevWndFunc:参数主要是指向你要调用的函数句柄 hWnd:指向接收消息的窗口过程的句柄。 M

求知者 2678

CallWindowProc与setwindowlong 用法

<br />该函数CallWindowProc将消息信息传送给指定的窗口过程。<br /><br />    函数原型:LRESULT CallWindowProc(WNDPROC lpPrevWndFunc,HWND hWnd.UINT Msg,WPARAM wParam,LPARAMIParam);<br /><br />    参数:<br /><br />    lpPrevWndFunc:参数主要是指向你要调用的函数句柄<br /><br />    hWnd:指向接收消息的窗口过程的句柄。<br

Steven Lei的博客 1万+

GetClassLong()、SetClassLong()、SetWindowLong()、GetWindowLong()

GetWindowLong/SetWindowLong是是读取和设置一个窗口的相关属性的,而GetClassLong/SetClassLong是读取/设置窗口类属性的,前者只是对一个窗口起作用,而后者则对所有从这个窗口类中创建的窗口都起作用。

发展是曲折的但也是前进的 2102
上一篇: 浏览器内核概述·
下一篇: VC绘制位图--BeginPaint()与GetDC()的区别和双缓冲
liuxingbin
博客等级 码龄20年 16粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值