문제

My questions are very simple and not very important.

  1. I began to learn writing Win32 applications. When I read code from other people, I often see that they put PAINTSTRUCT ps; before the switch statement in WndProc. Why don't they put this into the case WM_PAINT? They allocate memory for ps and then don't use it?

  2. I always see PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);. But I checked the value of ps.hdc multiple times and the values of ps.hdc and hdc are equal everytime. Is there another reason for defining hdc than just readability or writing less code?

(And sorry, if my English is bad and the questions aren't at the level of this community)

도움이 되었습니까?

해결책

To answer Point 1: The Win32 API was designed for C (it is quite old) and to put the PAINTSTRUCT ps; inside the case statement would require putting the contents of the case inside braces {} as C doesn't allow for inline declarations. C++ may also have a problem declaring variables inside case statements without the braces - calling destructors without calling the constructor. You will quickly find that the switch() case... style will become awkward to maintain, the function will become quite large and unwieldy and it doesn't play well with things like Intellisense. Quite often, you'll see developers use a map to associate functions with specific messages:-

WindowProc (args)
{
  func_ptr = some_map.GetValue (message_type)
  if func_ptr not null
    call func_ptr
  else
    DefWindowProc (args)
}

As for Point 2, the value of hdc will be null when there's an error and it's looks cleaner to use hdc instead of ps.hdc. Also, an hdc is easier to pass to other functions than a ps. But apart from that, the documentation doesn't call out any reason why ps.hdc would be different to the result of BeginPaint.

다른 팁

When I read code from other people, I often see that they put PAINTSTRUCT ps; before the switch statement in WndProc. Why don't they put this into the case WM_PAINT?

Several possibilities:

  1. They are or were using an older style of C where all local variables have to be defined at the beginning of a function.
  2. Depending on your compiler and its warning level, you can get warnings when trying to declare variables inside cases in a switch statement.
  3. They're just being sloppy.

A window procedure probably shouldn't "handle" the messages but instead dispatch them to message-specific handlers. Thus the WM_PAINT case in the WndProc should probably call a separate function that does the painting, and the PAINTSTRUCT could be local to that separate function. But we're venturing into opinion, so I'll leave it at that.

I always see PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);.

I seem to recall there was an obscure case where the returned device context handle could be different than the one in the PAINTSTRUCT, but was probably extremely rare and may not exist in modern versions of Windows.

Consider the returned HDC a convenience. If your painting is simple and doesn't need any of the other fields in the PAINTSTRUCT, this gives you an easy way to refer to the device context.

  1. It really makes no difference, and many implementations will "allocate" the memory every time the window procedure is called whether the variables are declared at the top of the function or within the WM_PAINT case of the switch.

  2. BeginPaint does more than simply return ps.hdc.

I often see that they put PAINTSTRUCT ps; before the switch statement in WndProc. Why don't they put this into the case WM_PAINT? They allocate memory for ps and then don't use it?

It's bad practice to do so. Best practice is to call a separate function to do the painting and avoid having a window procedure that is pages long. But if you have to paint in the window procedure, declare your variables with as local a scope as possible.

Is there another reason for defining hdc than just readability or writing less code?

It's a convenience. Since a paint function refers again and again to the device context, it is convenient to store it in a local variable and so make the code less verbose. And yes, when BeginPaint succeeds, it is guaranteed that the HDC returned by BeginPaint is equal to the HDC in the paint struct.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top