首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

为什么在WM_CREATE消息中,GetSystemMetrics 得不到窗口边框高宽?要如何改,或换在哪个消息中

2014-01-17 
为什么在WM_CREATE消息中,GetSystemMetrics 得不到窗口边框高宽?要怎么改,或换在哪个消息中?本帖最后由 ws

为什么在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);
}

试试

热点排行