Ceytar
دوشنبه 24 بهمن 1390, 18:33 عصر
این برنامه هنوز کامل نشده(اجرا می شه،ولی هنوز بخش هایش مونده) ، دو تا مشکل دارم . بازیی هست که (نسخه جاوا اسکریپتش رو احتمالا تو نت دیدید) فرضا 5 6 تا مربع باشه که سریع و راندوم حرکت می کنن و کاربر هم یک مربع داره و اون رو حرکت می ده ... اگر مربع ها همپوشانی داشته باشن کاربر ببازه !!
اولی ساده است : چطور می تونم یه جا مثلا وقتی می خوام بلافاصله ویندوز به تابع مدیریت پنجره من پیغام WM_PAINT بفرسته ؟ این رو هم مثل پاینی یه حالت بلافاصله و real time می خوام .
دومی اینه : اگه این برنامه رو کامپایل کنید می بینید که مربع رو می شه کشید اون ور این ور ... ولی یه حالت real time نیست . مثلا وقتی یه کم سریع تر بخوایی موس رو حرکت بدید . مربع جا می مونه . فکر کنم این بخاطر اینکه که ویندوز message queue برای پنجره رو با WM_MOUSEMOVE پر نمی کنه و یه نوعی فقط مقداری که قابل پردازش هست برای برنامه می فرسته . حالا سوال من اینه . من فکر می کنم با چند نخی بشه این رو پیاده کرد که یه حالت realtime باشه . ولی چون چند نخی بلد نیستم و این برنامه رو هم برا تفریح می نوشتم راه دیگه ای هست ؟؟ مثلا تابعی که به ویندوز اطلاع بده تمام event های موس رو بدون کم و کسری برا پردازش بفرسته و یا یه همچین چیزی ؟؟
سوال سوم: سوالم اینه که چطوری می شه برای سایز برنامه محدودیت قائل شد ؟ مثلا از یه حد کوچیکتر نشه (حالا بزرگتر مشکل نداره) ؟؟ با چه توابعی ؟؟
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int drawsq(HDC ,POINT *);
void setq(int x , int y,POINT *pt);
static TCHAR ncls[] = TEXT ("test") ;
static int siq = 25 ;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE
hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
MSG msg ;
WNDCLASS wc ;
HWND hwnd ;
wc.cbClsExtra = NULL ;
wc.cbWndExtra = NULL ;
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance = hInstance ;
wc.lpfnWndProc = WndProc ;
wc.lpszMenuName = NULL ;
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.lpszClassName = ncls ;
if (!RegisterClass (&wc))
{
MessageBox (NULL, TEXT ("This program requires NT!!"),
ncls, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow(ncls,L"test",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NU LL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while( GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
int drawsq(HDC hdc,POINT *pt){
int i = 0 ;
SelectObject (hdc , GetStockObject (GRAY_BRUSH)) ;
for(i = 0 ; i < 2 ; i++){
MoveToEx (hdc, (pt+i)->x, (pt+i)->y, NULL);
LineTo(hdc, (pt+i+1)->x, (pt+i+1)->y) ;
}
MoveToEx (hdc, (pt+3)->x, (pt+3)->y, NULL);
LineTo(hdc, (pt)->x, (pt)->y) ;
SetPolyFillMode (hdc, ALTERNATE) ;
Polygon (hdc, pt , 4) ;
return 0 ;
}
void setq(int x , int y,POINT *mypt){
(mypt)->x = x - (siq) ;
(mypt)->y = y - (siq) ;
(mypt+1)->x = x + (siq) ;
(mypt+1)->y = y - (siq) ;
(mypt+2)->x = x + (siq) ;
(mypt+2)->y = y + (siq) ;
(mypt+3)->x = x - (siq) ;
(mypt+3)->y = y + (siq) ;
return ;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wP,LPARAM lP ){
HDC hdc ;
static POINT mypt[4];
static int cxClient,cyClient,tmpx,tmpy,x,y;
PAINTSTRUCT ps ;
RECT rt ;
switch(msg)
{
case WM_CREATE:
{
GetClientRect(hwnd,&rt);
cxClient = rt.right - rt.left ;
cyClient = rt.bottom - rt.top ;
tmpx = cxClient/2;
tmpy = cyClient/2;
setq(tmpx,tmpy,mypt);
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
return 0;
}
case WM_SIZE :
cxClient = LOWORD (lP) ;
cyClient = HIWORD (lP) ;
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
SendMessage(hwnd,WM_PAINT,NULL,NULL);
return 0 ;
case WM_MOUSEMOVE:
{
if (!(wP & MK_LBUTTON))
return 0;
x = LOWORD (lP) ;
y = HIWORD (lP) ;
if( ( x > mypt[0].x) && (x < mypt[1].x) && (x < mypt[2].x) && (x > mypt[3].x) ){
if( ( y > mypt[0].y) && (y > mypt[1].y) && (y < mypt[2].y) && (y < mypt[3].y) ){
setq(x,y,mypt);
InvalidateRect (hwnd,NULL, TRUE) ;
UpdateWindow(hwnd);
SendMessage(hwnd,WM_PAINT,NULL,NULL);
}
}
return 0 ;
}
case WM_LBUTTONUP:
{
InvalidateRect(hwnd,NULL,FALSE);
UpdateWindow(hwnd);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
drawsq(hdc,mypt);
EndPaint (hwnd, &ps) ;
break;
}
}
return DefWindowProc(hwnd, msg, wP, lP);
}
اولی ساده است : چطور می تونم یه جا مثلا وقتی می خوام بلافاصله ویندوز به تابع مدیریت پنجره من پیغام WM_PAINT بفرسته ؟ این رو هم مثل پاینی یه حالت بلافاصله و real time می خوام .
دومی اینه : اگه این برنامه رو کامپایل کنید می بینید که مربع رو می شه کشید اون ور این ور ... ولی یه حالت real time نیست . مثلا وقتی یه کم سریع تر بخوایی موس رو حرکت بدید . مربع جا می مونه . فکر کنم این بخاطر اینکه که ویندوز message queue برای پنجره رو با WM_MOUSEMOVE پر نمی کنه و یه نوعی فقط مقداری که قابل پردازش هست برای برنامه می فرسته . حالا سوال من اینه . من فکر می کنم با چند نخی بشه این رو پیاده کرد که یه حالت realtime باشه . ولی چون چند نخی بلد نیستم و این برنامه رو هم برا تفریح می نوشتم راه دیگه ای هست ؟؟ مثلا تابعی که به ویندوز اطلاع بده تمام event های موس رو بدون کم و کسری برا پردازش بفرسته و یا یه همچین چیزی ؟؟
سوال سوم: سوالم اینه که چطوری می شه برای سایز برنامه محدودیت قائل شد ؟ مثلا از یه حد کوچیکتر نشه (حالا بزرگتر مشکل نداره) ؟؟ با چه توابعی ؟؟
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int drawsq(HDC ,POINT *);
void setq(int x , int y,POINT *pt);
static TCHAR ncls[] = TEXT ("test") ;
static int siq = 25 ;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE
hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
MSG msg ;
WNDCLASS wc ;
HWND hwnd ;
wc.cbClsExtra = NULL ;
wc.cbWndExtra = NULL ;
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance = hInstance ;
wc.lpfnWndProc = WndProc ;
wc.lpszMenuName = NULL ;
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.lpszClassName = ncls ;
if (!RegisterClass (&wc))
{
MessageBox (NULL, TEXT ("This program requires NT!!"),
ncls, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow(ncls,L"test",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NU LL);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while( GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
int drawsq(HDC hdc,POINT *pt){
int i = 0 ;
SelectObject (hdc , GetStockObject (GRAY_BRUSH)) ;
for(i = 0 ; i < 2 ; i++){
MoveToEx (hdc, (pt+i)->x, (pt+i)->y, NULL);
LineTo(hdc, (pt+i+1)->x, (pt+i+1)->y) ;
}
MoveToEx (hdc, (pt+3)->x, (pt+3)->y, NULL);
LineTo(hdc, (pt)->x, (pt)->y) ;
SetPolyFillMode (hdc, ALTERNATE) ;
Polygon (hdc, pt , 4) ;
return 0 ;
}
void setq(int x , int y,POINT *mypt){
(mypt)->x = x - (siq) ;
(mypt)->y = y - (siq) ;
(mypt+1)->x = x + (siq) ;
(mypt+1)->y = y - (siq) ;
(mypt+2)->x = x + (siq) ;
(mypt+2)->y = y + (siq) ;
(mypt+3)->x = x - (siq) ;
(mypt+3)->y = y + (siq) ;
return ;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wP,LPARAM lP ){
HDC hdc ;
static POINT mypt[4];
static int cxClient,cyClient,tmpx,tmpy,x,y;
PAINTSTRUCT ps ;
RECT rt ;
switch(msg)
{
case WM_CREATE:
{
GetClientRect(hwnd,&rt);
cxClient = rt.right - rt.left ;
cyClient = rt.bottom - rt.top ;
tmpx = cxClient/2;
tmpy = cyClient/2;
setq(tmpx,tmpy,mypt);
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
return 0;
}
case WM_SIZE :
cxClient = LOWORD (lP) ;
cyClient = HIWORD (lP) ;
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
SendMessage(hwnd,WM_PAINT,NULL,NULL);
return 0 ;
case WM_MOUSEMOVE:
{
if (!(wP & MK_LBUTTON))
return 0;
x = LOWORD (lP) ;
y = HIWORD (lP) ;
if( ( x > mypt[0].x) && (x < mypt[1].x) && (x < mypt[2].x) && (x > mypt[3].x) ){
if( ( y > mypt[0].y) && (y > mypt[1].y) && (y < mypt[2].y) && (y < mypt[3].y) ){
setq(x,y,mypt);
InvalidateRect (hwnd,NULL, TRUE) ;
UpdateWindow(hwnd);
SendMessage(hwnd,WM_PAINT,NULL,NULL);
}
}
return 0 ;
}
case WM_LBUTTONUP:
{
InvalidateRect(hwnd,NULL,FALSE);
UpdateWindow(hwnd);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
drawsq(hdc,mypt);
EndPaint (hwnd, &ps) ;
break;
}
}
return DefWindowProc(hwnd, msg, wP, lP);
}