我创建了一个主窗口,在主窗口的WM_CREATE消息的响应函数中再创建两个子窗口,在主窗口的WM_SIZE消息的响应函数中将两个子窗口设置为各占主窗口的一半(左、右)。现在我的设想是在第一子窗口中连续显示1、2、3、4、5、…,在第二个子窗口中随机填充矩形。这两项功能我都放在线程中完成,并设计了如下数据结构:
typedef struct
{
HWND hwnd;   //子窗口句柄
BOOL bKilled;  //子线程是否终止
int cxClient;  //子窗口的宽度
int cyClient;  //子窗口的高度
int cyChar;   //字符高度
}MYDATA,*PMYDATA;请大家帮我看看第2个线程中的Sleep()语句,若这句没注释,程序正常运行,若这句注释,则窗口立即变为全屏,整个程序显得杂乱无章,不知为何?请高手指教,谢谢!#include "windows.h"
#include "stdio.h"
#include "process.h"LRESULT CALLBACK MyWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);LRESULT CALLBACK WndProc1(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK WndProc2(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);int CheckLine(HWND hwnd,int Height,int iLine,int iChar)
{
if((iLine+1)*iChar>=Height)
{
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
iLine=0;
}
return iLine;
}typedef struct
{
HWND hwnd;
BOOL bKilled;
int cxClient;
int cyClient;
int cyChar;
}MYDATA,*PMYDATA;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
HWND hwnd;
MSG msg; WNDCLASS ClsWnd;
ClsWnd.cbClsExtra=0;
ClsWnd.cbWndExtra=0;
ClsWnd.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
ClsWnd.hCursor=LoadCursor(NULL,IDC_ARROW);
ClsWnd.hIcon=LoadIcon(NULL,IDI_WINLOGO);
ClsWnd.hInstance=hInstance;
ClsWnd.lpfnWndProc=MyWindowProc;
ClsWnd.lpszClassName=TEXT("lgh");
ClsWnd.lpszMenuName=NULL;
ClsWnd.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&ClsWnd))
{
MessageBox(NULL,TEXT("注册窗口类不成功"),TEXT("注册窗口类"),MB_OK);
return 0;
}
hwnd=CreateWindow(TEXT("lgh"),TEXT("li_guang_hua"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}LRESULT CALLBACK MyWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
int i;
WNDCLASS wndcls;
int cxClient,cyClient;
TCHAR * WndClassName[]={TEXT("MyChildWnd1"),TEXT("MyChildWnd2")};
static HWND hChildWnd[2];
static WNDPROC MyWndProc[]={WndProc1,WndProc2};

switch(uMsg)
{
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return 0;
case WM_CREATE:
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wndcls.hIcon=NULL;
wndcls.hInstance=((LPCREATESTRUCT)lParam)->hInstance;
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW|CS_VREDRAW;

for(i=0;i<2;i++)
{
wndcls.lpfnWndProc=MyWndProc[i];
wndcls.lpszClassName=WndClassName[i];
RegisterClass(&wndcls);
hChildWnd[i]=CreateWindow(WndClassName[i],NULL,WS_CHILDWINDOW|WS_VISIBLE|WS_BORDER,0,0,0,0,hwnd,NULL,((LPCREATESTRUCT)lParam)->hInstance,NULL);
}
return 0;
case WM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
for(i=0;i<2;i++)
{
MoveWindow(hChildWnd[i],i*cxClient/2,0,cxClient/2,cyClient,TRUE);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);

}//thread 1 function in childwindow1
DWORD WINAPI Thread1(PVOID pvoid)
{
MYDATA * mythreaddata;
HDC hdc;
int i,iLineNum;
char ch[50];

i=0;
iLineNum=-1;
mythreaddata=(PMYDATA)pvoid;
while(!(mythreaddata->bKilled))
{
if(i<0)
i=0;
iLineNum++;
hdc=GetDC(mythreaddata->hwnd);
sprintf(ch,"%d",i);
iLineNum=CheckLine(mythreaddata->hwnd,mythreaddata->cyClient,iLineNum,mythreaddata->cyChar);
TextOut(hdc,0,iLineNum*mythreaddata->cyChar,ch,lstrlen(ch));
++i;
ReleaseDC(mythreaddata->hwnd,hdc);
}
return 0;

}
//Child Window1 Proc
LRESULT CALLBACK WndProc1(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
HANDLE hThread;
static MYDATA mydata1;
ULONG id1;

switch(uMsg)
{
case WM_CREATE:
mydata1.bKilled=FALSE;
mydata1.hwnd=hwnd;
mydata1.cyChar=HIWORD(GetDialogBaseUnits());
hThread=CreateThread(NULL,0,Thread1,(PVOID)&mydata1,0,&id1); 
CloseHandle(hThread);
return 0;
case WM_SIZE:
mydata1.cxClient=LOWORD(lParam);
mydata1.cyClient=HIWORD(lParam);
return 0;
case WM_DESTROY:
mydata1.bKilled=TRUE;
return 0;

}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
//thread 2 function in childwindow2
DWORD WINAPI Thread2(PVOID pvoid)
{
MYDATA * mythreaddata;
HDC hdc;
int cx,cy;
int RectLeft,RectTop,RectRight,RectBottom; mythreaddata=(PMYDATA)pvoid;
while(!(mythreaddata->bKilled))
{
cx=mythreaddata->cxClient;
cy=mythreaddata->cyClient;
RectLeft=rand()%max(2,cx);
RectTop=rand()%max(2,cy);
RectRight=rand()%max(2,cx);
RectBottom=rand()%max(2,cy); //sprintf(ch,"left:%d,top:%d,right:%d,bottom:%d",RectLeft,RectTop,RectRight,RectBottom);
//MessageBox(NULL,ch,NULL,MB_OK); hdc=GetDC(mythreaddata->hwnd);
RECT rect;
rect.left=RectLeft;
rect.top=RectTop;
rect.right=RectRight;
rect.bottom=RectBottom; InvalidateRect(mythreaddata->hwnd,NULL,TRUE);
UpdateWindow(mythreaddata->hwnd);
FillRect(hdc,&rect,CreateSolidBrush(RGB(255,0,0)));
ReleaseDC(mythreaddata->hwnd,hdc); Sleep(1);        //这句注释与不注释大不一样,不知为何?
}
return 0;

}
LRESULT CALLBACK WndProc2(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
HANDLE hThread;
static MYDATA mydata2;
ULONG id2;

switch(uMsg)
{
case WM_CREATE:
mydata2.bKilled=FALSE;
mydata2.hwnd=hwnd;
mydata2.cyChar=0; hThread=CreateThread(NULL,0,Thread2,(PVOID)&mydata2,0,&id2); 
CloseHandle(hThread);
return 0;
case WM_SIZE:
mydata2.cxClient=LOWORD(lParam);
mydata2.cyClient=HIWORD(lParam);
return 0;
case WM_DESTROY:
mydata2.bKilled=TRUE;
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

解决方案 »

  1.   

    注意一点:sleep执行期间,CPU被100%占用!其它线程是不会执行的!
      

  2.   

    第2个线程中的Sleep()语句,若这句没注释,程序正常运行,若这句被注释,则窗口立即变为全屏,整个程序显得杂乱无章,不知为何?
    有注释与没注释连窗口的大小都不一样,这是为什么?
      

  3.   

    原因不在sleep()上。是程序本身有问题。
      

  4.   

    我的本意是用多线程体验的Windows的强制多任务,所以就不用定时器了。请问有哪位高手运行过我的代码吗?
      

  5.   

    不要在多线程中使用sleep,你可以使用waitforsingleobject来等待某段时间,否则CPU肯定占用率100%
      

  6.   

    waitforsingleobject来等待某段时间?等待什么时间?Windows的强制多任务是各线程执行20ms,然后就要交出CPU,用不用Sleep()有什么关系?反倒是用Sleep()立即交出CPU.
      

  7.   

    不要在多线程中使用sleep,你可以使用waitforsingleobject来等待某段时间,否则CPU肯定占用率100%乱讲,
    我就在多线程服务中使用SLEEP控制,
    一共300多线程[线程池技术],30在线,CPU占用7%都没有,运行一直很稳定。