SetFocus(scrollHwnd[idFocus]); return 0; case WM_COMMAND: switch(LOWORD(wParam)){ case ID_REDBUTTON: EnableWindow(scrollHwnd[ID_REDSCROLL],notFrozen[ID_REDSCROLL]^=true); break; case ID_BLUEBUTTON: EnableWindow(scrollHwnd[ID_BLUESCROLL],notFrozen[ID_BLUESCROLL]^=true); break; case ID_GREENBUTTON: EnableWindow(scrollHwnd[ID_GREENSCROLL],notFrozen[ID_GREENSCROLL]^=true); break; } return 0; case WM_MOUSEMOVE: int mx,my; mx=LOWORD(lParam); my=HIWORD(lParam); if((mx>0 && mx<cxClient) && (my>0 && my<cyClient/2)){ DeleteObject((HBRUSH)SetClassLong(hwnd,GCL_HBRBACKGROUND, (long)CreateSolidBrush(RGB(scrollPos[ID_REDSCROLL]+mx%256, scrollPos[ID_BLUESCROLL]+my%256, scrollPos[ID_GREENSCROLL]+(mx+my)%256)))); InvalidateRect(hwnd,0,true); }
return 0; case WM_DESTROY: for(i=0; i<3; i++) DeleteObject(hBrush[i]); DeleteObject((HBRUSH) SetClassLong(hwnd,GCL_HBRBACKGROUND, (long)GetStockObject(WHITE_BRUSH))); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }LRESULT CALLBACK ScrollProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ int ctrlID=GetDlgCtrlID(hwnd); switch(message){ case WM_HSCROLL: switch(LOWORD(wParam)){ case SB_PAGERIGHT: scrollPos[ctrlID]+=15; case SB_LINERIGHT: scrollPos[ctrlID]=min(225,scrollPos[ctrlID]+1); break;
case SB_PAGELEFT: scrollPos[ctrlID]-=15; case SB_LINELEFT: scrollPos[ctrlID]=max(0,scrollPos[ctrlID]-1); break; case SB_THUMBPOSITION: case SB_THUMBTRACK: scrollPos[ctrlID]=HIWORD(wParam); break; }
而wndclass方式主要是在程序创建初期就定下来了。
用子窗口控制Scrollbar,但是,滑块会弹回的.我尝试不用子窗口,到是可以的.问题出在哪里啊?我想"子窗口"过程里的hwnd就是每个Scrollbar的句柄
#include <windows.h>
#include "resource.h"const int ID_REDSCROLL=0;
const int ID_BLUESCROLL=1;
const int ID_GREENSCROLL=2;const int ID_REDBUTTON=3;
const int ID_BLUEBUTTON=4;
const int ID_GREENBUTTON=5;const int ID_TABLE=6;int idFocus;
int scrollPos[3];
WNDPROC scrollProc[3];LRESULT CALLBACK WndProc (HWND, UINT, WPARAM , LPARAM );
LRESULT CALLBACK ScrollProc (HWND, UINT , WPARAM , LPARAM );
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("ColorTable") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = sizeof(long);
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance,TEXT ("ColorTable")) ;
wndclass.hCursor = LoadCursor (0,IDC_CROSS) ;
wndclass.hbrBackground = (HBRUSH) (GetStockObject(BLACK_BRUSH)) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)){
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("ColorTable"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0)){
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
static HBRUSH hBrush[3];
static bool notFrozen[3];
static HWND tableHwnd,scrollHwnd[3],colorLableHwnd[3];
static int cxClient,cyClient,cxChar,cyChar; int i,id;
COLORREF color[3]={RGB(225,0,0),
RGB(0,0,225),
RGB(0,225,0)
}; switch(message){
case WM_CREATE:
tableHwnd=CreateWindow(TEXT("static"),0,
WS_CHILD|WS_VISIBLE|SS_WHITERECT,
0,0,0,0,
hwnd,(HMENU)ID_TABLE,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),0);
SetClassLong(tableHwnd,GCL_HCURSOR,
(long)LoadCursor((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
MAKEINTRESOURCE(IDC_POINTER))); for(i=0; i<3; i++){
scrollHwnd[i]=CreateWindow(TEXT("scrollbar"),0,
WS_CHILD|WS_VISIBLE|WS_TABSTOP|SBS_HORZ,
0,0,0,0,
hwnd,(HMENU)i,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),0);
SetScrollRange(scrollHwnd[i],SB_CTL,0,225,true);
SetScrollPos(scrollHwnd[i],SB_CTL,0,true);
scrollProc[i]=(WNDPROC)SetWindowLong(scrollHwnd[i],GWL_WNDPROC,(long)ScrollProc); hBrush[i]=CreateSolidBrush(color[i]);
notFrozen[i]=true; colorLableHwnd[i]=CreateWindow(TEXT("button"),0,
WS_CHILD|WS_VISIBLE|WS_BORDER|BS_OWNERDRAW,
0,0,0,0,
hwnd,(HMENU)(i+3),(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),0);
} return 0; case WM_CTLCOLORSCROLLBAR:
i=GetDlgCtrlID((HWND)lParam);
return (LRESULT)hBrush[i]; case WM_DRAWITEM:
RECT rc;
LPDRAWITEMSTRUCT pdis;
int cx,cy;
pdis=(LPDRAWITEMSTRUCT)lParam;
cx=pdis->rcItem.right-pdis->rcItem.left;
cy=pdis->rcItem.bottom-pdis->rcItem.top; FrameRect(pdis->hDC,&pdis->rcItem,(HBRUSH)GetStockObject(BLACK_BRUSH)); switch(pdis->CtlID){
case ID_REDBUTTON:
FillRect(pdis->hDC,&pdis->rcItem,CreateSolidBrush(RGB(225,0,0)));
break; case ID_BLUEBUTTON:
FillRect(pdis->hDC,&pdis->rcItem,CreateSolidBrush(RGB(0,0,225)));
break; case ID_GREENBUTTON:
FillRect(pdis->hDC,&pdis->rcItem,CreateSolidBrush(RGB(0,225,0)));
break;
}
if(pdis->itemState & ODS_SELECTED)
InvertRect(pdis->hDC,&pdis->rcItem);
if(pdis->itemState & ODS_FOCUS){
rc.left =pdis->rcItem.left + cx/16;
rc.right =pdis->rcItem.right - cx/16;
rc.top =pdis->rcItem.top + cy/12;
rc.bottom=pdis->rcItem.bottom- cy/12; DrawFocusRect(pdis->hDC,&rc);
} return 0; case WM_SIZE:
cxChar=LOWORD(GetDialogBaseUnits());
cyChar=HIWORD(GetDialogBaseUnits());
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam); MoveWindow(tableHwnd,0,cyClient/2,cxClient,cyClient/2,true);
for(i=0; i<3; i++){
MoveWindow(scrollHwnd[i],cxClient/8,(i+3)*cyClient/6+cyChar,
7*cxClient/8-cxChar,cyChar,true);
MoveWindow(colorLableHwnd[i],cxChar,(i+3)*cyClient/6+cyChar,
cxClient/10,cyChar,true);
}
SetFocus(scrollHwnd[idFocus]);
return 0;
case WM_COMMAND:
switch(LOWORD(wParam)){
case ID_REDBUTTON:
EnableWindow(scrollHwnd[ID_REDSCROLL],notFrozen[ID_REDSCROLL]^=true);
break; case ID_BLUEBUTTON:
EnableWindow(scrollHwnd[ID_BLUESCROLL],notFrozen[ID_BLUESCROLL]^=true);
break; case ID_GREENBUTTON:
EnableWindow(scrollHwnd[ID_GREENSCROLL],notFrozen[ID_GREENSCROLL]^=true);
break;
} return 0; case WM_MOUSEMOVE:
int mx,my;
mx=LOWORD(lParam);
my=HIWORD(lParam); if((mx>0 && mx<cxClient) && (my>0 && my<cyClient/2)){
DeleteObject((HBRUSH)SetClassLong(hwnd,GCL_HBRBACKGROUND,
(long)CreateSolidBrush(RGB(scrollPos[ID_REDSCROLL]+mx%256,
scrollPos[ID_BLUESCROLL]+my%256,
scrollPos[ID_GREENSCROLL]+(mx+my)%256))));
InvalidateRect(hwnd,0,true);
}
return 0; case WM_DESTROY:
for(i=0; i<3; i++)
DeleteObject(hBrush[i]); DeleteObject((HBRUSH)
SetClassLong(hwnd,GCL_HBRBACKGROUND,
(long)GetStockObject(WHITE_BRUSH))); PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}LRESULT CALLBACK ScrollProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
int ctrlID=GetDlgCtrlID(hwnd); switch(message){
case WM_HSCROLL:
switch(LOWORD(wParam)){
case SB_PAGERIGHT:
scrollPos[ctrlID]+=15;
case SB_LINERIGHT:
scrollPos[ctrlID]=min(225,scrollPos[ctrlID]+1);
break;
case SB_PAGELEFT:
scrollPos[ctrlID]-=15;
case SB_LINELEFT:
scrollPos[ctrlID]=max(0,scrollPos[ctrlID]-1);
break; case SB_THUMBPOSITION:
case SB_THUMBTRACK:
scrollPos[ctrlID]=HIWORD(wParam);
break;
}
SetScrollPos(hwnd,SB_CTL,scrollPos[ctrlID],true); DeleteObject((HBRUSH)
SetClassLong(GetParent(hwnd),GCL_HBRBACKGROUND,
(long)CreateSolidBrush(RGB(scrollPos[ID_REDSCROLL],
scrollPos[ID_BLUESCROLL],
scrollPos[ID_GREENSCROLL]))));
InvalidateRect(GetParent(hwnd),0,true);
return 0;
case WM_KEYDOWN:
switch(wParam){
case VK_TAB:
SetFocus(GetDlgItem(GetParent(hwnd),(ctrlID+1)%3));
idFocus=(ctrlID+1)%3;
break;
}
return 0;
} return CallWindowProc(scrollProc[ctrlID],hwnd,message,wParam,lParam);
}
在ScrollProc函数中接收不了WM_HSCROLL消息,我也觉得奇怪。可能这条消息是由父窗口处理吧?
我在你的程序的WndProc函数中加了条语句,由父窗口传递一条消息。
case WM_HSCROLL:
SendMessage((HWND) lParam,WM_HSCROLL,wParam,lParam);
return 0;
就可以了。现在我的问题是:到底子控制可以接收哪些消息。
哥们你是如何想到的.我个人认为,没有道理呀?我当时设计主窗口过程的时候没有加入任何滚动条风格呀?应该不会有主窗口的WM_HSCROLL.想不通?
窗口子类化的前提是目标窗口已经创建!
我明白了,WM_HSCROLL是由卷滚条向父窗口发送的一条消息,所以自己不能直接接收了。mfc中的反射就是用的这个原理,将发往父窗口的消息再由父窗口反射回来,就可以解决了。
我更加糊了.
在"子过程"中
hwnd是scrollbar,如何是父窗口?
scrollbar----------------------->父窗口
<-----------------------
反馈回去WM_HSCROLL消息WM_HSCROLL是由scrollbar向外发出的,你的最初的程序一开始就在scrollbar中接收,殊不知WM_HSCROLL是由scrollbar向外发出的。
windows编程中是不是大多是按照这种发送与反馈的机制呢?