小发现,关于windows窗口中的F10快捷键
今天本来在学习Direct3D9,运行一个窗口的时候发觉,如果在键盘上按下F10,画面就会停止,再按一下F10以后,画面又继续显示。
后来打开其他程序再测试,发觉原来是按F10的时候就相当于按下了选中菜单的快捷键(相当于Alt键)。
而众所周知,当一个窗口在拖动之类的情况下是不会更新画面的。于是就有了这种奇怪的表现。
可是我的窗口明明没有菜单,却可以被选中?(在win7系统下得出的结果)这可以说完全是一个多余的特性了。
想要关掉这个特性,可以选择在窗口回调中截获WM_SYSKEYDOWN或者WM_SYSKEYUP这两个消息的其中一个,那么就不会产生这种奇怪的效果了。
例如:
1 case WM_SYSKEYDOWN:
2 // case WM_SYSKEYUP:
3 case WM_KEYUP:
4 if(wParam == VK_ESCAPE)DestroyWindow(hWnd);
5 if(wParam == VK_F10)SetWindowText(hWnd,"F10 Pressed!");
6 break;
不过这又让我想起了另外一件事。
平时我遇到的多数程序,都会在被鼠标拖动的期间不再更新画面,而播放器程序却不会这样。那些播放器是怎么做到这一点的呢?
顺便贴下刚刚的测试:
代码
1 #include <d3dx9.h>
2 LRESULT CALLBACK MsgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
3 {
4 switch(uMsg){
5 case WM_DESTROY:
6 PostQuitMessage(0);
7 break;
8 case WM_SYSKEYUP:
9 if(wParam == VK_F10)SetWindowText(hWnd,"F10 Pressed!");
10 case WM_KEYUP:
11 if(wParam == VK_ESCAPE)DestroyWindow(hWnd);
12 break;
13 default:
14 return DefWindowProc(hWnd,uMsg,wParam,lParam);
15 }
16 return 0;
17 }
18 HWND SetupWindow(){
19 WNDCLASS wcls = {0,MsgProc,0,0,GetModuleHandle(0),
20 LoadIcon(NULL,IDI_WINLOGO),LoadCursor(NULL,IDC_ARROW),
21 (HBRUSH)(COLOR_WINDOW + 1),0,"classname"};
22 RegisterClass(&wcls);
23 return CreateWindow("classname","D3D Demo",WS_SYSMENU,
24 CW_USEDEFAULT,0,CW_USEDEFAULT,0,
25 NULL,NULL,GetModuleHandle(0),0);
26 }
27 IDirect3DDevice9 *SetupD3D(){
28 HWND hwnd = SetupWindow();
29 ShowWindow(hwnd,SW_SHOWNORMAL);
30 UpdateWindow(hwnd);
31 IDirect3D9 *d3d = Direct3DCreate9(D3D_SDK_VERSION);
32 D3DPRESENT_PARAMETERS
33 d3dpp = {0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,0,
34 D3DSWAPEFFECT_DISCARD,hwnd,true,true,D3DFMT_D24S8,0,0,0};
35 IDirect3DDevice9 *d3dDevice;
36 d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,
37 D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&d3dDevice);
38 {
39 D3DXVECTOR3 position(0.0f,0.0f,-5.0f);
40 D3DXVECTOR3 target(0.0f,0.0f,0.0f);
41 D3DXVECTOR3 up(0.0f,1.0f,0.0f);
42 D3DXMATRIX v;
43 D3DXMatrixLookAtLH(&v,&position,&target,&up);
44 d3dDevice->SetTransform(D3DTS_VIEW,&v);
45 }
46 {
47 D3DVIEWPORT9 vp;
48 d3dDevice->GetViewport(&vp);
49
50 D3DXMATRIX proj;
51 D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI / 4.0f,(float)vp.Width/(float)vp.Height,1.0f,1000.0f);
52 d3dDevice->SetTransform(D3DTS_PROJECTION,&proj);
53 }
54 d3dDevice->SetRenderState(D3DRS_LIGHTING,false);
55 //d3dDevice->SetRenderState(D3DRS_ZENABLE,false);
56 return d3dDevice;
57 }
58 int EnterMsgLoop(IDirect3DDevice9 *d3dDevice9,bool (*ptr_display)(IDirect3DDevice9 * d3dDevice9,float timeDelta))
59 {
60 MSG msg;
61 static float lastTime = (float)timeGetTime();
62 while(true){
63 if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
64 if(msg.message == WM_QUIT)break;
65 else{
66 TranslateMessage(&msg);
67 DispatchMessage(&msg);
68 }
69 }
70 else{
71 float currTime = (float)timeGetTime();
72 float timeDelta = (currTime - lastTime) * 0.001f;
73 ptr_display(d3dDevice9,timeDelta);
74 lastTime = currTime;
75 }
76 }
77 d3dDevice9->Release();
78 return (int)msg.wParam;
79 }
80 IDirect3DVertexBuffer9* GetVertexBuffer(IDirect3DDevice9 *d3dDevice,D3DCOLOR color)
81 {
82 struct vertex{float x,y,z;D3DCOLOR color;};
83 static IDirect3DVertexBuffer9 *_pVertexBuffer = NULL;
84 static DWORD oldColor = 0;
85 if(_pVertexBuffer && oldColor == color){
86 return _pVertexBuffer;
87 }
88 else if(_pVertexBuffer){
89 struct vertex *pVertices;
90 _pVertexBuffer->Lock(0,0,(void**)&pVertices,0);
91 for(int i=0;i<8;i++)pVertices[i].color = color;
92 _pVertexBuffer->Unlock();
93 return _pVertexBuffer;
94 }
95
96 struct vertex vertices[8] =
97 {
98 { -1.0f, -1.0f },
99 { -1.0f, 1.0f },
100 { 1.0f, 1.0f },
101 { 1.0f, -1.0f },
102 };
103 d3dDevice->CreateVertexBuffer(
104 sizeof vertices,0,
105 D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_MANAGED,&_pVertexBuffer,0);
106
107 memcpy(&vertices[4],&vertices[0],4*sizeof(struct vertex));
108 for(int i = 0;i < 8;i += 1){
109 //vertices[i] = i < 4 ? -1.0f : 1.0f;
110 if(i < 4)
111 vertices[i].z = -1.0f;
112 else
113 vertices[i].z = 1.0f;
114 vertices[i].color = D3DCOLOR_XRGB(255,0,0);
115 }
116 void *pBuffer;
117 _pVertexBuffer->Lock(0,0,&pBuffer,0);
118 memcpy(pBuffer,vertices,sizeof vertices);
119 _pVertexBuffer->Unlock();
120 return _pVertexBuffer;
121 }
122 IDirect3DIndexBuffer9 *BoxIndexBuffer(IDirect3DDevice9 *d3dDevice)
123 {
124 static IDirect3DIndexBuffer9 *_pIndexBuffer = NULL;
125 if(_pIndexBuffer){
126 return _pIndexBuffer;
127 }
128 d3dDevice->CreateIndexBuffer(
129 36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
130 D3DPOOL_MANAGED,&_pIndexBuffer,0);
131 WORD indices[36] =
132 {
133 0,1,2, 0,2,3,
134 1,5,6, 1,6,2,
135 2,6,7, 2,7,3,
136 4,6,5, 4,7,6,
137 0,4,1, 1,4,5,
138 0,3,7, 0,7,4,
139 };
140 void *pBuffer;
141 _pIndexBuffer->Lock(0,0,&pBuffer,0);
142 memcpy(pBuffer,indices,sizeof indices);
143 _pIndexBuffer->Unlock();
144 return _pIndexBuffer;
145 }
146 IDirect3DIndexBuffer9 *OutlineIndexBuffer(IDirect3DDevice9 *d3dDevice)
147 {
148 static IDirect3DIndexBuffer9 *_pIndexBuffer = NULL;
149 if(_pIndexBuffer){
150 return _pIndexBuffer;
151 }
152 d3dDevice->CreateIndexBuffer(
153 24*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
154 D3DPOOL_MANAGED,&_pIndexBuffer,0);
155 WORD indices[24] =
156 {
157 0,1, 1,2, 2,3, 3,0,
158 5,4, 6,5, 7,6, 4,7,
159 4,0, 5,1, 2,6, 3,7,
160 };
161 void *pBuffer;
162 _pIndexBuffer->Lock(0,0,&pBuffer,0);
163 memcpy(pBuffer,indices,sizeof indices);
164 _pIndexBuffer->Unlock();
165 return _pIndexBuffer;
166 }
167 bool Display(IDirect3DDevice9 *d3dDevice,float timeDelta)
168 {
169 d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0xffffffff,1.0f,0);
170 D3DXMATRIX Rx,Ry;
171 static float x = 0.0f;
172 D3DXMatrixRotationX(&Rx,x);
173 static float y = 0.0f;
174 D3DXMatrixRotationY(&Ry,y);
175 y += timeDelta*0.3;
176 x += timeDelta*0.1;
177 if(y >= 2*D3DX_PI)
178 y = 0.0f;
179 D3DXMATRIX p = Rx * Ry;
180 d3dDevice->SetTransform(D3DTS_WORLD, &p);
181 d3dDevice->BeginScene();
182
183 d3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
184
185
186
187 d3dDevice->SetIndices(BoxIndexBuffer(d3dDevice));
188 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(255,0,0)),0,3*sizeof(float)+sizeof(DWORD));
189 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,2);
190 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(255,255,0)),0,3*sizeof(float)+sizeof(DWORD));
191 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,6,2);
192 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(255,0,255)),0,3*sizeof(float)+sizeof(DWORD));
193 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,12,2);
194
195 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(0,255,0)),0,3*sizeof(float)+sizeof(DWORD));
196 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,18,2);
197 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(0,255,255)),0,3*sizeof(float)+sizeof(DWORD));
198 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,24,2);
199 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(0,0,255)),0,3*sizeof(float)+sizeof(DWORD));
200 d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,30,2);
201
202 d3dDevice->SetIndices(OutlineIndexBuffer(d3dDevice));
203 d3dDevice->SetStreamSource(0,GetVertexBuffer(d3dDevice,D3DCOLOR_XRGB(0,0,0)),0,3*sizeof(float)+sizeof(DWORD));
204
205 //d3dDevice->DrawIndexedPrimitive(D3DPT_LINELIST,0,0,8,0,12);
206
207 d3dDevice->EndScene();
208 d3dDevice->Present(0,0,0,0);
209 return true;
210 }
211 int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
212 {
213 IDirect3DDevice9 *d3dDevice = SetupD3D();
214 return EnterMsgLoop(d3dDevice,Display);
215 }
216