ورود

View Full Version : سوال: يك سوال كوچك درباره WindowProc در win32



cpp.mfc
شنبه 01 اسفند 1388, 15:35 عصر
سلام
دربرنامه win32 ساده زير درتابع WindowProc قبل از دستور switch يك متن نمايش داده مي شود و در پيامهاي دستور switch همان دستور نمايش متن گذاشته شده فقط نمي دونم چرا فقط دستور قبل از switch اجرا ميشود ؟؟؟
در چه صورتي دستور درون switch اجرا ميشود ؟؟




#include <windows.h>

LRESULT WINAPI WindowProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);

// Insert code for WinMain() here (Listing OFWIN_1)
// Listing OFWIN_1
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX WindowClass; // Structure to hold our window's attributes

static LPCTSTR szAppName = "OFWin"; // Define window class name
HWND hWnd; // Window handle
MSG msg; // Windows message structure

WindowClass.cbSize = sizeof(WNDCLASSEX); // Set structure size

// Redraw the window if the size changes
WindowClass.style = CS_HREDRAW | CS_VREDRAW;

// Define the message handling function
WindowClass.lpfnWndProc = WindowProc;

WindowClass.cbClsExtra = 0; // No extra bytes after the window class
WindowClass.cbWndExtra = 0; // structure or the window instance
WindowClass.hInstance = hInstance;
WindowClass.hIcon = LoadIcon(0, IDI_ASTERISK);
// Set window cursor to be the standard arrow
WindowClass.hCursor = LoadCursor(0, IDC_HELP);
// Set gray brush for background color
WindowClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(DKGRAY_BRUSH));
WindowClass.lpszMenuName = 0; // No menu
WindowClass.lpszClassName = szAppName; // Set class name
WindowClass.hIconSm =0; // Default small icon
RegisterClassEx(&WindowClass);
hWnd = CreateWindow(
szAppName, // the window class name
" يك برنامه ساده ", // The window title
WS_OVERLAPPEDWINDOW, // Window style as overlapped
500, // Default screen position of upper left
200, // corner of our window as x,y...
300, // Default window size
100, // ....
0, // No parent window
0, // No menu
hInstance, // Program Instance handle
0 // No window creation data
);

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

while(GetMessage(&msg, 0, 0, 0) == TRUE) // Get any messages
{
TranslateMessage(&msg); // Translate the message
DispatchMessage(&msg); // Dispatch the message
}

return static_cast<int>(msg.wParam); // End, so return to Windows
}

// Insert code for WindowProc() here (Listing OFWIN_2)
// Listing OFWIN_2

LRESULT WINAPI WindowProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)
{
HDC hDC; // Display context handle
PAINTSTRUCT PaintSt; // Structure defining area to be drawn
RECT aRect; // A working rectangle

hDC = BeginPaint(hWnd, &PaintSt);// Prepare to draw the window

// Get upper left and lower right of client area
GetClientRect(hWnd, &aRect);

SetBkMode(hDC, TRANSPARENT); // Set text background mode

// Now draw the text in the window client area

DrawText(
hDC, // Device context handle
"switch نمايش متن قبل از دستور ",
-1, // Indicate null terminated string
&aRect, // Rectangle in which text is to be drawn
DT_SINGLELINE| // Text format - single line
DT_CENTER| // - centered in the line
DT_VCENTER
);
EndPaint(hWnd, &PaintSt);

switch(message) // Process selected messages
{
case WM_PAINT: // Message is to redraw the window
hDC = BeginPaint(hWnd, &PaintSt);// Prepare to draw the window

// Get upper left and lower right of client area
GetClientRect(hWnd, &aRect);

SetBkMode(hDC, TRANSPARENT); // Set text background mode

// Now draw the text in the window client area

DrawText(
hDC, // Device context handle
"switch نمايش متن در دستور ",
-1, // Indicate null terminated string
&aRect, // Rectangle in which text is to be drawn
DT_SINGLELINE| // Text format - single line
DT_CENTER| // - centered in the line
DT_VCENTER
); // - line centered in aRect

EndPaint(hWnd, &PaintSt); // Terminate window redraw operation
return 0;

case WM_DESTROY: // Window is being destroyed
PostQuitMessage(0);
return 0;

default: // Any other message - we don't
// want to know, so call
// default message processing
return DefWindowProc(hWnd, message, wParam, lParam);
}
}

Nima_NF
شنبه 01 اسفند 1388, 16:09 عصر
شما حتما باید کتاب مطالعه کنید تا با پیام های ویندوز آشنا شوید. مواردی که داخل switch هست هر کدام یک پیام در ویندوز هست. مثلا WM_PAINT پیام کشیدن اشکال هست، که ممکن هست در یک ثانیه هزاران مرتبه فراحوانی شود و یا خودتان با توابعی خاصی مانند updatewindow برنامه را وادار به اجرای این پیام کنید.

ضمنا کدی که شما نوشتید کاملا غلط هست. خارج از switch شما اجازه ندارید از BeginPaint استفاده کنید. این دستور فقط باید داخل پیام WM_PAINT فراخوانی شود.

نکات بسیاری وجود دارد، تا کتاب مطالعه کنید و کار پیام ها را فرا نگیرید، نمی توانید برنامه بنویسید.

cpp.mfc
یک شنبه 02 اسفند 1388, 16:36 عصر
سلام
خيلي ممنونم از جوابتون :
من تازه شروع به كار با win32 كردم و ميدونم كه در دستور switch بايد پيامهاي ويندوز را نوشت ، سوال من اين بود كه چرا وقتي دستورهاي زير را قبل از دستور switch مينويسم پيام هاي درون دستور switch اجرا نميشود و فقط دستور قبل از switch اجرا مي شود و من مجبورم ازupdatewindow استفاده بكنم ؟؟ :متفکر:

hDC = BeginPaint(hWnd, &PaintSt);// Prepare to draw the window

// Get upper left and lower right of client area
GetClientRect(hWnd, &aRect);

SetBkMode(hDC, TRANSPARENT); // Set text background mode

// Now draw the text in the window client area

DrawText(
hDC, // Device context handle
"switch نمايش متن قبل از دستور ",
-1, // Indicate null terminated string
&aRect, // Rectangle in which text is to be drawn
DT_SINGLELINE| // Text format - single line
DT_CENTER| // - centered in the line
DT_VCENTER
);
EndPaint(hWnd, &PaintSt);

در ضمن برنامه غلط نيست چون به صورت زير اجرا شده است ...
http://barnamenevis.org/forum/attachment.php?attachmentid=44460&stc=1&d=1266758670

متشكرم Nima_NF
موفق باشيد

Nima_NF
یک شنبه 02 اسفند 1388, 19:49 عصر
در پست قبلی علت را به شما گفتم که عمل نکردید.

همیشه وقتی از API ها استفاده می کنید باید آن را در MSDN چک کنید تا مطمئن شوید که همه قوانین را در مورد استفاده از ان تابع رعایت می کنید.

نکته برگرفته از MSDN:



An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to the EndPaint function



پس وقتی پیام WM_PAINT ارسال می شود برنامه شما درست کار می کند، اما وقتی پیام دیگری هست، برنامه خطای ناشناس دریافت می کند.

پس برای رفع مشکل قطعه کد پست قبلی خود را داخل WM_PAINT بنویسید.
اگر قرار هست خارج از این پیام چیزیی رسم کنید، باید از GetDC به جای BeginPaint استفاده کنید.