2011-04-28 2 views
1

...왜 다음 코드가 작동하지 않습니까? 내 프로그램의 곳에서 나는 다음과 같은 스타일을 사용하여 정적 컨트롤을 만들었습니다

picBoxDisp = CreateWindow("STATIC", "image box", 
     WS_VISIBLE |WS_CHILD | SS_BITMAP |WS_TABSTOP | WS_BORDER, 
     50, 50, 250, 300, 
     hwnd , (HMENU)10000, NULL, NULL); 

SetWindowLongPtr(picBoxDisp,GWLP_WNDPROC,(LONG) dispWndProc); 

는 다음 코드 ..

SendMessage(picBoxDisp,STM_SETIMAGE, (WPARAM) IMAGE_BITMAP,(LPARAM) hBitmap); 

이제 dispWndProc 내부에서 나는 다음과 같은 코드가 있습니다. lParam에 다시 HBITMAP에 캐스트 나던 왜 IMG가 NULL 이유.

LRESULT CALLBACK dispWndProc(HWND hwnd,UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
static HDC hdc; 
static PAINTSTRUCT paintSt; 
static RECT aRect; 
switch(msg) 
{ 
    case WM_PAINT: 
    { 
     hdc = BeginPaint(hwnd,&paintSt); 
     GetClientRect(hwnd,&aRect);      
     // the code for painting 
     EndPaint(hwnd,&paintSt); 
    } 
    break; 
    case STM_SETIMAGE: 
    { 

     //painting code; 
     HBITMAP img = (HBITMAP)lParam; 
     BITMAP bmp; 
     GetObject(img,sizeof(bmp),&bmp); 
     HDC imgDC = GetDC((HWND)img); 
     HDC memDC = CreateCompatibleDC(imgDC); 
     SelectObject(memDC,img); 
     if((img==NULL))// ||(imgDC==NULL)||(memDC==NULL)) 
     { 

        MessageBox(NULL,"img is NULL","Bad Programming!!! Error",MB_OK); 

     } 

     else 

     { 
     StretchBlt(hdc,0,0,aRect.right,aRect.bottom, 
     memDC,0,0,bmp.bmWidth,bmp.bmHeight, 
     SRCCOPY); 
     } 

    } 
     break; 
    default: 
     return DefWindowProc(hwnd,msg,wParam,lParam); 

} 

return 0; 
} 

는 사람이 .... 알 수 있습니까? 사전에

덕분에,

+1

왜 자신의 클래스를 만드는 대신 정적 컨트롤을 서브 클래스로 만드나요? 일반적으로 기존 기능 중 일부를 사용하고 사용자 지정하려는 경우가 아니면 다른 컨트롤을 하위 클래스로 만들지 않습니다. STM_SETIMAGE에서 페인팅 코드를 수행하는 것은 이상합니다. 일반적으로 비트 맵 핸들을 저장하고 InvalidateRect를 호출 한 다음 WM_PAINT에서 모두 페인팅합니다. 또한; SetWindowLongPtr에서 LONG_PTR로 캐스트하고 LONG으로 캐스트하지 않습니다. LONG으로 형변환하면 win64 용으로 컴파일 할 때이 코드가 실패 할 수 있습니다. – BrendanMcK

답변

2

그것은 다른 코드는 또한 당신의 창으로 STM_SETIMAGE를 보내는 것이 가능하다. SendMessage(STM_SETIMAGE) 번에 전화를 건 횟수와 case STM_SETIMAGE에 도달 한 횟수를 세어보십시오.


또한 HDC imgDC = GetDC((HWND)img);도 절대로 작동하지 않습니다. HBITMAPHWND이 아닙니다.

+0

전체 프로그램에서 STM_SETIMAGE를 한 번만 보내고 있습니다. (위에서 쓴 줄) .... – aProgrammer

+0

@Arts : 작성하지 않은 코드는 무엇입니까? 운영 체제는 다양한 이유로 Windows에 메시지를 전송합니다. –

+0

@Ben Voigt : 편집 된 코드를 참조하십시오. 이것은 주 창의 하위 패널에있는 정적 상자입니다. 나는 그것을 고치는 법을 모른다. SendMessage() 및 STM_SETIMAGE의 API는 lParam이 이미지 전송 핸들을 가지고 있으며이 정적 컨트롤에 별도의 WNDPROC를 추가하기 전에 코드가 정상적으로 작동하고 있다고 말합니다. 나는 WIN32에서 새로운데, 오류를 찾을 수 없습니다. ..... Nyway에게 도움을 청하는 친구. – aProgrammer

2

이 코드에는 여러 가지 문제가 있습니다.

  1. 당신은 WM_PAINT 처리를 제외하고 어디 BeginPaint/EndPaint을 사용할 수 없습니다. 다른 문제를 고려하기 전에 문제를 해결하십시오.
  2. 다음으로, 창을 올바르게 서브 클래 싱하고 있는지 확실하지 않습니다. 이전 창 proc에서 CallWindowProc으로 전화하십시오.
  3. 당신이보고있는 것이 실제로 당신이보고있는 것이라고 확신하는 것은 까다로운 일입니다. 예를 들어 Ben Voigt가 말했듯이, 아마도 당신은 그것을 보낸 사람이 아닙니다. 어쩌면 위의 스위치 케이스 블록이 손상되었을 수도 있습니다. 어쩌면 당신은 NULL로 넘어 갔을 것입니다.

이러한 것들부터 시작하면 더 가까이 다가갑니다.

+0

제안에 따라 코드를 편집했지만 img 변수는 여전히 NULL입니다 ... 그리고 HBITMAP 객체의 DC를 얻는 방법 ... ur 시간 동안 감사드립니다. – aProgrammer

+1

당신은 여전히'CallWindowProc'를 호출하지 않습니다. 'DefWindowProc'은 전혀 같지 않습니다; 컨트롤은 올바른 하위 클래스 화 기술 없이는 작동하지 않습니다. – tenfour

+0

CallWindowProc을 어디서 사용해야합니까? 기본 섹션에서? 어떤 WNDPROC를 dispWndProc (정적 컨트롤의 WNDPROC), child1WndProc (정적 컨트롤을 소유하고있는 패널의 WNDPROC) 또는 MyWndProc (자식 윈도우의 부모)를 ..... 호출해야합니까? WIN32의 새로운 기능 .. 다시 한번 감사드립니다. – aProgrammer

관련 문제