读书人

为什么在WM_CREATE消息中GetSystemM

发布时间: 2014-01-17 00:06:00 作者: rapoo

为什么在WM_CREATE消息中,GetSystemMetrics 得不到窗口边框高宽?要怎么改,或换在哪个消息中?
本帖最后由 wsfxzxb 于 2013-09-08 11:21:12 编辑 代码如下:

// 军棋记棋器,影子制作

#include<windows.h>
#include"resource.h"


const int W=28,H=21;
#define IDM_SYS_ABOUT 1
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,PSTR lpCmdLine,int nShowCmd)
{
TCHAR szAppName[] = TEXT ("JQQ") ;
HWND hWnd;
MSG msg;
WNDCLASS WndClass;

WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WinProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(hInstance,TEXT("JunQi"));
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = szAppName;

if(!RegisterClass(&WndClass))
{
MessageBox(NULL,TEXT("程序需要 Windows NT!"),szAppName,MB_ICONERROR);
return 0;
}

hWnd = CreateWindow(szAppName, TEXT("点击棋子计棋"),
WS_POPUP|WS_SYSMENU|WS_CAPTION,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);

HMENU hMenu = GetSystemMenu (hWnd, FALSE) ;
AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
AppendMenu (hMenu, MF_STRING, IDM_SYS_ABOUT, TEXT ("影子制作 QQ:115142074")) ;

ShowWindow(hWnd,nShowCmd);
UpdateWindow(hWnd);

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}



LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
int x=0,y=0,i,j;
HDC hdc,hdcMem;
static HANDLE hBmp,hSem;
static BOOL liveBlue[27],liveGreen[27];
static HINSTANCE hInstance ;
PAINTSTRUCT ps;

switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
for(i=0;i!=27;++i)
{
liveBlue[i]=true;
liveGreen[i]=true;
}
// 用应用程序名创建信号内核对象
hSem = CreateSemaphore(NULL,1,1,TEXT ("JQQ"));

// 信号对象存在,则已有一个实例运行
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hSem);
hBmp = LoadBitmap(hInstance,TEXT("green"));
// 在这儿 ,GetSystemMetrics 得不到对话框边框宽度和高度,总是为0
// 但是标题栏高度可以得到,else分支也是一样
SetWindowPos(hWnd,HWND_TOPMOST,GetSystemMetrics(SM_CXSCREEN)-W*6-6*2, 0,
W*6 + GetSystemMetrics(SM_CXFIXEDFRAME)*2,
H*4 + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION) ,
SWP_SHOWWINDOW);
}
else
{
hBmp = LoadBitmap(hInstance,TEXT("blue"));

SetWindowPos(hWnd,HWND_TOPMOST,0,0,
28*6 + GetSystemMetrics(SM_CXFIXEDFRAME)*2,
21*4 + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION) ,
SWP_SHOWWINDOW);
}
return 0;

case WM_LBUTTONDOWN:
x = LOWORD(lParam)/W;
y = HIWORD(lParam)/H;
liveBlue[6*y+x]=!liveBlue[6*y+x];
InvalidateRect(hWnd,NULL,TRUE);
return 0;

case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);

hdcMem = CreateCompatibleDC (hdc) ;


for(j=0;j!=24;++j)
{
switch(j)
{
case 0: // 工兵
case 1:
case 2:
i=liveBlue[j]?1:0; x=j*W,y=0;break;

case 3: // 地雷
case 4:
case 5:
i=liveBlue[j]?2:0; x=j*W,y=0;break;

case 6: // 炸弹
case 7:
i=liveBlue[j]?3:0;x=(j-6)*W,y=H; break;

case 8: // 司令
i=liveBlue[j]?4:0;x=(j-6)*W,y=H; break;

case 9: // 军长
i=liveBlue[j]?5:0;x=(j-6)*W,y=H; break;

case 10:// 师长
case 11:
i=liveBlue[j]?6:0;x=(j-6)*W,y=H; break;

case 12:// 旅长
case 13:
i=liveBlue[j]?7:0;x=(j-12)*W,y=2*H;break;

case 14:// 团长
case 15:
i=liveBlue[j]?8:0;x=(j-12)*W,y=2*H;break;

case 16:// 营长
case 17:
i=liveBlue[j]?9:0;x=(j-12)*W,y=2*H;break;

case 18:// 连长
case 19:
case 20:
i=liveBlue[j]?10:0;x=(j-18)*W,y=3*H;break;

case 21:// 排长
case 22:
case 23:
i=liveBlue[j]?11:0;x=(j-18)*W,y=3*H;break;
}
SelectObject(hdcMem, hBmp) ;
BitBlt (hdc, x, y, W, H, hdcMem, i*W, 0, SRCCOPY) ;
}

DeleteDC (hdcMem) ;
EndPaint(hWnd,&ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}


[解决办法]
我的~ 作平台 Windows 8 Pro...幕解析 1680x1050...以您的代得 SM_CXSCREEN = 1680 . SM_CXFIXEDFRAME = 3 . SM_CYCAPTION = 23
行果只有第一窗口在左上方位置...之後行的窗口皆在右上方位置但右有 6 Pixels 距~
另外...WndClass.style 添加 WS_EX_LAYERED 可以改善窗口容示速度~
[解决办法]
可以通过
void SetDlgPosition(HWND hDLG)
{
INT ScreenX=0,ScreenY=0;
ScreenX=GetSystemMetrics(SM_CXSCREEN);
ScreenY=GetSystemMetrics(SM_CYSCREEN);
RECT rt;
GetWindowRect(hDLG,&rt);
ScreenX=(ScreenX-rt.right-rt.left)/2;
ScreenY=(ScreenY-rt.bottom-rt.top)/2;
MoveWindow(hDLG,ScreenX,ScreenY,rt.right-rt.left,rt.bottom-rt.top,FALSE);
}

试试

读书人网 >C++ Builder

热点推荐