显示标签为“window”的博文。显示所有博文
显示标签为“window”的博文。显示所有博文

2012年3月26日星期一

windows中的多线程处理

(一)建立新线程的函数


1.Win32 API函数 CreateThread
HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);


2.也可以用C运行库的函数 _beginthread 来创建新线程
uintptr_t _beginthread( 
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);


(二)线程间通讯方法:


1.消息通讯
可以在线程中用SendMessage发送自定义消息到指定窗口
LRESULT WINAPI SendMessage(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam
);


2.创建线程时可以传递一个结构体的指针
3.利用全局变量来通讯

对Window程序消息循环的理解



  • 1.每个(创建窗口的)线程有一个消息队列,程序用下面的循环接收、转换消息,并将消息分发到合适的窗口处理程序:



    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }



  • 2.windows系统负责把消息放入每个线程的消息队列或者直接调用合适的窗口处理程序




  • 3.Post消息和Send消息的区别



    a. Post一个消息(可以调用API函数PostMessage)表示消息将经过消息队列,通过消息循环来分发消息
    b. Send一个消息(可以调用API函数SendMessage)表示消息会跳过消息队列,操作系统直接调用窗口处理程序



  • 4.可以在任意线程中发送自定义的消息(消息值>= WM_USER)到指定的窗口




  • 5.消息队列


    操作系统维护一个系统消息队列并为每一个GUI线程维护一个线程消息队列。为了避免为非GUI线程创建消息队列的开销,所有的线程在最初创建时没有消息队列。仅当线程第一次调用特定的用户函数时系统才创建一个线程消息队列;没有任何GUI函数的调用会导致消息队列的创建。


  • 6.队列消息和非队列消息


    a. 队列消息

    移动或点击鼠标、敲击键盘等大部分消息为队列消息。
    仅当消息队列中没有其它消息时,WM_PAINTWM_TIMERWM_QUIT消息才被发送到窗口处理程序。
    其它的消息按先进先出的原则被发送到窗口处理程序
    用户可以用PostMessage等函数来发送一个队列消息

    b. 非队列消息

    比如当窗口转为active状态时,或者用户调用某些系统函数(如SetWindowPos)时,消息将跳过消息队列,直接发往窗口处理程序。
    用户可以调用SendMessage等函数来发送一个非队列消息


2011年5月6日星期五

jQuery获取window、document、dom元素的高度和宽度函数分析

以下为获取高度或宽度函数的jQuery源代码

// 创建jQuery.height(size) jQuery.width(size)
//调用each方法创建两个相似的函数
jQuery.each([ "Height", "Width" ], function( i, name ) {

var type = name.toLowerCase();

jQuery.fn[ type ] = function( size ) {

var elem = this[0];
if ( !elem ) {
return size == null ? null : this;
}

if ( jQuery.isFunction( size ) ) {
return this.each(function( i ) {
var self = jQuery( this );
self[ type ]( size.call( this, i, self[ type ]() ) );
});
}

// 获取window对象的高度或宽度 ($(window).width() ) 实际上是当前可见区域的高度或宽度
if ( jQuery.isWindow( elem ) ) {
// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
// 以上英文的意思是依赖于Quirks 或 Standards 文档模式来使用
// document.documentElement (实际上就是元素) 或 document.body
var docElemProp = elem.document.documentElement[ "client" + name ];
return elem.document.compatMode === "CSS1Compat" && docElemProp ||
elem.document.body[ "client" + name ] || docElemProp;

// 获取整个文档对象(document)的宽度或高度
} else if ( elem.nodeType === 9 ) {
// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
return Math.max(
elem.documentElement["client" + name],
elem.body["scroll" + name], elem.documentElement["scroll" + name],
elem.body["offset" + name], elem.documentElement["offset" + name]
);

// 获取DOM元素的高度或宽度
} else if ( size === undefined ) {
var orig = jQuery.css( elem, type ),
ret = parseFloat( orig );

return jQuery.isNaN( ret ) ? orig : ret;

// 设置DOM元素的高度或宽度 (当没有单位时默认为像素值)
} else {
return this.css( type, typeof size === "string" ? size : size + "px" );
}
};

});

jQuery(window).height()代表了当前可见区域的大小,而jQuery(document).height()则代表了整个文档的高度,可视具体情况使用
注意当浏览器窗口大小改变时(如最大化或拉大窗口后) jQuery(window).height() 随之改变,但是jQuery(document).height()是不变的。