如何分别控制第一个显示器的分辨率,第二个显示器或者TV的分辨率或者窗口的大小
如何知道显卡具有TwinView功能,如何知道他是复制还是水平延伸还是垂直延伸

解决方案 »

  1.   

    你用API函数得到屏幕的显示分辨率,如果是640X960,800X1200等就是垂直延伸,如果是1280X480,1600X600等就是水平延伸.
      

  2.   

    需要的话告诉我你的信箱我给你发格例子:
    /*----------------------------------------------------------------------------*|   MMHELP.C - routines to help a app be multimonitor aware
    \*----------------------------------------------------------------------------*/#include <windows.h>
    #include <windowsx.h>
    #include "multimon.h"//
    //  GetMonitorRect
    //
    //  gets the "screen" or work area of the monitor that the passed
    //  window is on.  this is used for apps that want to clip or
    //  center windows.
    //
    //  the most common problem apps have with multimonitor systems is
    //  when they use GetSystemMetrics(SM_C?SCREEN) to center or clip a
    //  window to keep it on screen.  If you do this on a multimonitor
    //  system the window we be restricted to the primary monitor.
    //
    //  this is a example of how you used the new Win32 multimonitor APIs
    //  to do the same thing.
    //
    void GetMonitorRect(HWND hwnd, LPRECT prc, BOOL fWork)
    {
        MONITORINFO mi;    mi.cbSize = sizeof(mi);
        GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &mi);    if (fWork)
            *prc = mi.rcWork;
        else
            *prc = mi.rcMonitor;
    }//
    // ClipRectToMonitor
    //
    // uses GetMonitorRect to clip a rect to the monitor that
    // the passed window is on.
    //
    void ClipRectToMonitor(HWND hwnd, RECT *prc, BOOL fWork)
    {
        RECT rc;
        int  w = prc->right  - prc->left;
        int  h = prc->bottom - prc->top;    if (hwnd != NULL)
        {
            GetMonitorRect(hwnd, &rc, fWork);
        }
        else
        {
            MONITORINFO mi;        mi.cbSize = sizeof(mi);
            GetMonitorInfo(MonitorFromRect(prc, MONITOR_DEFAULTTONEAREST), &mi);        if (fWork)
                rc = mi.rcWork;
            else
                rc = mi.rcMonitor;
        }    prc->left   = max(rc.left, min(rc.right-w,  prc->left));
        prc->top    = max(rc.top,  min(rc.bottom-h, prc->top));
        prc->right  = prc->left + w;
        prc->bottom = prc->top  + h;
    }//
    // CenterRectToMonitor
    //
    // uses GetMonitorRect to center a rect to the monitor that
    // the passed window is on.
    //
    void CenterRectToMonitor(HWND hwnd, RECT *prc, BOOL fWork)
    {
        RECT rc;
        int  w = prc->right  - prc->left;
        int  h = prc->bottom - prc->top;    GetMonitorRect(hwnd, &rc, fWork);    prc->left = rc.left + (rc.right  - rc.left - w) / 2;
        prc->top = rc.top  + (rc.bottom - rc.top  - h) / 2;
        prc->right = prc->left + w;
        prc->bottom = prc->top  + h;
    }//
    // CenterWindowToMonitor
    //
    void CenterWindowToMonitor(HWND hwndP, HWND hwnd, BOOL fWork)
    {
        RECT rc;
        GetWindowRect(hwnd, &rc);
        CenterRectToMonitor(hwndP, &rc, fWork);
        SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
    }//
    // ClipWindowToMonitor
    //
    void ClipWindowToMonitor(HWND hwndP, HWND hwnd, BOOL fWork)
    {
        RECT rc;
        GetWindowRect(hwnd, &rc);
        ClipRectToMonitor(hwndP, &rc, fWork);
        SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
    }//
    // IsWindowOnScreen
    //
    BOOL IsWindowOnScreen(HWND hwnd)
    {
        HDC hdc;
        RECT rc;
        BOOL f;    GetWindowRect(hwnd, &rc);
        hdc = GetDC(NULL);
        f = RectVisible(hdc, &rc);
        ReleaseDC(NULL, hdc);
        return f;
    }//
    // MakeSureWindowIsVisible
    //
    void MakeSureWindowIsVisible(HWND hwnd)
    {
        if (!IsWindowOnScreen(hwnd))
        {
    ClipWindowToMonitor(hwnd, hwnd, TRUE);
        }
    }
      

  3.   

    TestMM.c
    void TestEnumDisplayDevices()
    {
        DWORD i;
        DISPLAY_DEVICE dd;
        DEVMODE dm;    AppPrint("");
        AppPrint("EnumDisplayDevices:");    ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);    __try
        {
            for(i=0; EnumDisplayDevices(NULL, i, &dd, 0); i++)
            {
                AppPrint("Device %d:", i);
                AppPrint("    DeviceName:   '%s'", dd.DeviceName);
                AppPrint("    DeviceString: '%s'", dd.DeviceString);
                AppPrint("    StateFlags:   %s%s%s%s",
                    ((dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ? "desktop " : ""),
                    ((dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE     ) ? "primary " : ""),
                    ((dd.StateFlags & DISPLAY_DEVICE_VGA                ) ? "vga "     : ""),
                    ((dd.StateFlags & DISPLAY_DEVICE_MULTI_DRIVER       ) ? "multi "   : ""),
                    ((dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER   ) ? "mirror "  : "") );            ZeroMemory(&dm, sizeof(dm));
                dm.dmSize = sizeof(dm);            EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm);
                AppPrint("    Current Settings %dx%dx%d",dm.dmPelsWidth,dm.dmPelsHeight,dm.dmBitsPerPel);            EnumDisplaySettings(dd.DeviceName, ENUM_REGISTRY_SETTINGS, &dm);
                AppPrint("    Registry Settings %dx%dx%d",dm.dmPelsWidth,dm.dmPelsHeight,dm.dmBitsPerPel);
            }
        }
        __except(1)
        {
            AppPrint("EnumDisplayDevices faulted!");
        }
    }/*----------------------------------------------------------------------------*\*----------------------------------------------------------------------------*/
    BOOL CALLBACK CallbackNull(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
    {
        return TRUE;
    }BOOL CALLBACK CallbackWindow(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
    {
        return TRUE;
    }BOOL CALLBACK CallbackRect(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
    {
        return TRUE;
    }BOOL CALLBACK CallbackScreen(HMONITOR hMonitor,HDC hdc,LPRECT prc,LPARAM lParam)
    {
        MONITORINFOEX mix;
        MONITORINFO mi;    mi.cbSize = sizeof(mi);
        GetMonitorInfo(hMonitor, &mi);    mix.cbSize = sizeof(mix);
        GetMonitorInfo(hMonitor, (MONITORINFO*)&mix);    AppPrint("Monitor %08X", hMonitor);
        AppPrint("      szDevice  = '%s'", (LPSTR)mix.szDevice);
        AppPrint("      rcMonitor = [%d,%d,%d,%d]", mi.rcMonitor);
        AppPrint("      rcWork    = [%d,%d,%d,%d]", mi.rcWork);
        AppPrint("      dwFlags   = %08X", mi.dwFlags);    if (hdc)
        {
            struct {
                BITMAPINFOHEADER bi;
                DWORD            ct[256];
            }   dib;        GetOptimalDIBFormat(hdc, &dib.bi);        AppPrint("      VREFRESH        = %d", GetDeviceCaps(hdc, VREFRESH       ));
            AppPrint("      DESKTOPVERTRES  = %d", GetDeviceCaps(hdc, DESKTOPVERTRES ));
            AppPrint("      DESKTOPHORZRES  = %d", GetDeviceCaps(hdc, DESKTOPHORZRES ));
            AppPrint("      BLTALIGNMENT    = %d", GetDeviceCaps(hdc, BLTALIGNMENT   ));        AppPrint("      HORZRES         = %d", GetDeviceCaps(hdc, HORZRES   ));
            AppPrint("      VERTRES         = %d", GetDeviceCaps(hdc, VERTRES   ));
            AppPrint("      PALETTE         = %s", (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? "Yes" : "No");
            AppPrint("      BITSPIXEL       = %d", GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES));        if (dib.bi.biCompression == BI_BITFIELDS)
            {
                if (dib.ct[0] == 0xF800 &&
                    dib.ct[1] == 0x07E0 &&
                    dib.ct[2] == 0x001F )
                {
                    AppPrint("      FORMAT          = 565");
                }            if (dib.ct[0] == 0x7C00 &&
                    dib.ct[1] == 0x03E0 &&
                    dib.ct[2] == 0x001F )
                {
                    AppPrint("      FORMAT          = 555");
                }            if (dib.ct[0] == 0xFF0000 &&
                    dib.ct[1] == 0x00FF00 &&
                    dib.ct[2] == 0x0000FF )
                {
                    AppPrint("      FORMAT          = BGR");
                }            if (dib.ct[0] == 0x0000FF &&
                    dib.ct[1] == 0x00FF00 &&
                    dib.ct[2] == 0xFF0000 )
                {
                    AppPrint("      FORMAT          = RGB");
                }
            }
        }    return TRUE;
    }/*----------------------------------------------------------------------------*\*----------------------------------------------------------------------------*/
    void TestEnumDisplayMonitors()
    {
        HDC hdc;
        RECT rc;    AppPrint("");
        AppPrint("EnumDisplayMonitors");    EnumDisplayMonitors(NULL, NULL, CallbackNull, 42);    hdc = GetDC(NULL);
        EnumDisplayMonitors(hdc, NULL, CallbackScreen, 42);
        ReleaseDC(NULL,hdc);    hdc = GetDC(hwndApp);
        EnumDisplayMonitors(hdc, NULL, CallbackWindow, 42);
        ReleaseDC(hwndApp,hdc);    GetWindowRect(hwndApp, &rc);
        EnumDisplayMonitors(NULL, &rc, CallbackRect, 42);
    }/*----------------------------------------------------------------------------*\*----------------------------------------------------------------------------*/void DoTestMM(HWND hwnd, LPARAM lParam)
    {
        HDC hdc;
        RECT rc;
        static HMONITOR hMonitorMe;
        HMONITOR hMonitor;
        hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);    if (hMonitorMe == hMonitor && lParam)
            return;    hMonitorMe = hMonitor;    AppPrint(NULL);    if (hMonitor)
        {
            MONITORINFOEX mi;
            mi.cbSize = sizeof(mi);
            GetMonitorInfo(hMonitor, (MONITORINFO*)&mi);        AppSetText(mi.szDevice);
            AppPrint("My Window is on hMonitor %08X",hMonitor);
        }
        else
        {
            AppSetText(NULL);
            AppPrint("My Window is not visible");
        }    AppPrint("");
        AppPrint("SM_CMONITORS         is %d", GetSystemMetrics(SM_CMONITORS));
        AppPrint("SM_SAMEDISPLAYFORMAT is %d", GetSystemMetrics(SM_SAMEDISPLAYFORMAT));
        AppPrint("SM_XVIRTUALSCREEN    is %d", GetSystemMetrics(SM_XVIRTUALSCREEN));
        AppPrint("SM_YVIRTUALSCREEN    is %d", GetSystemMetrics(SM_YVIRTUALSCREEN));
        AppPrint("SM_CXVIRTUALSCREEN   is %d", GetSystemMetrics(SM_CXVIRTUALSCREEN));
        AppPrint("SM_CYVIRTUALSCREEN   is %d", GetSystemMetrics(SM_CYVIRTUALSCREEN));    hdc = GetDC(NULL);
        GetClipBox(hdc, &rc);
        AppPrint("GetClipBox of GetDC(NULL)    = [%d,%d,%d,%d]", rc);
        ReleaseDC(NULL, hdc);    hdc = GetDC(GetDesktopWindow());
        GetClipBox(hdc, &rc);
        AppPrint("GetClipBox of GetDC(desktop) = [%d,%d,%d,%d]", rc);
        ReleaseDC(GetDesktopWindow(), hdc);    GetWindowRect(GetDesktopWindow(), &rc);
        AppPrint("GetWindowRect of desktop     = [%d,%d,%d,%d]", rc);    TestEnumDisplayMonitors();
        TestEnumDisplayDevices();
    }/*----------------------------------------------------------------------------*|   AppInit( hInst, hPrev)                                                     |
    \*----------------------------------------------------------------------------*/
    BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
    {
        WNDCLASS cls;
        int      dx,dy;    /* Save instance handle for DialogBoxs */
        hInstApp = hInst;    if (!hPrev)
        {
            /*
             *  Register a class for the main application window
             */
            cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
            cls.hIcon          = LoadIcon(hInst,"AppIcon");
            cls.lpszMenuName   = "AppMenu";
            cls.lpszClassName  = szAppName;
            cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
            cls.hInstance      = hInst;
            cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
            cls.lpfnWndProc    = (WNDPROC)AppWndProc;
            cls.cbWndExtra     = 0;
            cls.cbClsExtra     = 0;
      

  4.   


            if (!RegisterClass(&cls))
                return FALSE;
        }    dx = GetSystemMetrics (SM_CXSCREEN) / 2;
        dy = GetSystemMetrics (SM_CYSCREEN) / 2;    hwndApp = CreateWindow (szAppName,    // Class name
                                szAppName,              // Caption
                                WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                                CW_USEDEFAULT, 0,
        dx,dy,     // Size
                                (HWND)NULL,             // Parent window (no parent)
                                (HMENU)NULL,            // use class menu
                                hInst,                  // handle to window instance
                                (LPSTR)NULL             // no params to pass on
                               );
        ShowWindow(hwndApp,sw);
        return TRUE;
    }
    /*----------------------------------------------------------------------------*|   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
    |                                                                              |
    |   Description:                                                               |
    |       The window proc for the app's main (tiled) window.  This processes all |
    |       of the parent window's messages.                                       |
    |                                                                              |
    \*----------------------------------------------------------------------------*/
    LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
        HWND hwndC;    switch (msg)
        {
            case WM_COMMAND:
                switch (LOWORD(wParam))
                {
                    case ID_TEST_CENTERTOMONITOR:   
        CenterWindowToMonitor(hwnd, hwnd, FALSE); 
        break;
                    case ID_TEST_CENTERTOWORKAREA:  
        CenterWindowToMonitor(hwnd, hwnd, TRUE); 
        break;
                    case ID_TEST_CLIPTOMONITOR:     
        ClipWindowToMonitor(hwnd, hwnd, FALSE); 
        break;
                    case ID_TEST_CLIPTOWORKAREA:    
        ClipWindowToMonitor(hwnd, hwnd, TRUE); 
        break;
                    case ID_TEST_RUNNOTEPAD:
        ShellExecute(hwnd, "open", "notepad.exe", NULL, NULL, SW_SHOWNORMAL );
        break;
                }
                break;        case WM_KEYUP:
                if (wParam == VK_F5)
                    DoTestMM(hwnd, 0);
                break;        case WM_WINDOWPOSCHANGED:
                DoTestMM(hwnd, 1);
                break;        case WM_SETTINGCHANGE:
            case WM_DISPLAYCHANGE:
                DoTestMM(hwnd, 0);
                break; case WM_SIZE:
        if (hwndC = GetWindow(hwnd, GW_CHILD))
                    MoveWindow(hwndC, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
        break; case WM_DESTROY:
                PostQuitMessage(0);
        break;
        }
        return DefWindowProc(hwnd,msg,wParam,lParam);
    }/*----------------------------------------------------------------------------*|   ErrMsg - Opens a Message box with a error message in it.  The user can     |
    |            select the OK button to continue                                  |
    \*----------------------------------------------------------------------------*/
    int ErrMsg (LPSTR sz,...)
    {
        char ach[128];    wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
        MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
        return FALSE;
    }/*----------------------------------------------------------------------------*\*----------------------------------------------------------------------------*/
    void AppSetText(LPSTR sz,...)
    {
        char ach[128];    lstrcpy(ach, szAppName);    if (sz != NULL && *sz != 0)
        {
            lstrcat(ach, " - ");
            wvsprintf (ach+lstrlen(ach),sz,(LPSTR)(&sz+1));   /* Format the string */
        }
        SetWindowText(hwndApp, ach);
    }/*----------------------------------------------------------------------------*\*----------------------------------------------------------------------------*/
    void AppPrint(LPSTR sz,...)
    {
        HWND hwndE = GetWindow(hwndApp, GW_CHILD);
        char ach[128];    if (hwndE == NULL) 
        {
         RECT rc;
            GetClientRect(hwndApp, &rc);
            hwndE = CreateWindow ("Edit", "", 
                WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY | WS_VSCROLL | ES_AUTOVSCROLL,
                0, 0, rc.right, rc.bottom,
                hwndApp, (HMENU)-1, hInstApp, NULL);        SetWindowFont(hwndE, GetStockObject(ANSI_FIXED_FONT), TRUE);
        }    if (sz == NULL)
        {
         Edit_SetSel(hwndE, 0, (UINT)-1);
         Edit_ReplaceSel(hwndE, "");
        }
        else
        {
         wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
         lstrcat(ach, "\r\n");     Edit_SetSel(hwndE, (UINT)-1, (UINT)-1);
         Edit_ReplaceSel(hwndE, ach);
        }
    }/*----------------------------------------------------------------------------*|   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
    \*----------------------------------------------------------------------------*/
    int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
    {
        MSG     msg;
        DWORD   dw=0;    /* Call initialization procedure */
        if (!AppInit(hInst,hPrev,sw,szCmdLine))
            return FALSE;    /*
         * Polling messages from event queue
         */
        for (;;)
        {
            if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                    break;            TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else
    {
                WaitMessage();
            }
        }    return msg.wParam;
    }//
    //  GetOptimalDIBFormat
    //
    //   get the optimal DIB format for a display device.
    //   the optimal DIB format is the format that exactly
    //   matches the format of the device, this is very important
    //   when dealing with 16bpp modes, you need to know
    //   what bitfields to use (555 or 565 for example)
    //
    //   you normaly use this function to get the best
    //   format to pass to CreateDIBSection()
    //
    //  Input
    //   hdc device to get the optimal format for.
    //   pbi pointer to a bitmapinfo + color table
    //       (room for 256 colors are assumed)
    //
    //  Output
    //   pbi contains optimal DIB format, in the <= 8bpp case
    //       the color table will contain the system palette
    //       in the >=16bpp case the "color table" will contain
    //       the correct bit fields (see BI_BITFIELDS for more info)
    //
    //  Notes
    //   if you are going to use this function on a 8bpp device
    //   you should make sure the colortable contains a indentity
    //   palette for optimal blt'ing
    //
    void GetOptimalDIBFormat(HDC hdc, BITMAPINFOHEADER *pbi)
    {
        HBITMAP hbm;
        hbm = CreateCompatibleBitmap(hdc, 1, 1);
        ZeroMemory(pbi, sizeof(BITMAPINFOHEADER));
        pbi->biSize = sizeof(BITMAPINFOHEADER);
        pbi->biBitCount = 0;
        // first call will fill in the optimal biBitCount
        GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
        // second call will get the optimal color table, or the optimal bitfields
        GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
        DeleteObject(hbm);
    }