zoukankan      html  css  js  c++  java
  • directdraw的多画面显示rgb 分类: VC++ 2013-11-13 08:51 514人阅读 评论(0) 收藏

    // showpicDlg.cpp : 实现文件
    //

    #include "stdafx.h"
    #include "showpic.h"
    #include "showpicDlg.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif


    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框

    class CAboutDlg : public CDialog
    {
    public:
     CAboutDlg();

    // 对话框数据
     enum { IDD = IDD_ABOUTBOX };

     protected:
     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    // 实现
    protected:
     DECLARE_MESSAGE_MAP()
    };

    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    }

    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
     CDialog::DoDataExchange(pDX);
    }

    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    END_MESSAGE_MAP()


    // CshowpicDlg 对话框


    CshowpicDlg::CshowpicDlg(CWnd* pParent /*=NULL*/)
     : CDialog(CshowpicDlg::IDD, pParent)
    {
     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }

    void CshowpicDlg::DoDataExchange(CDataExchange* pDX)
    {
     CDialog::DoDataExchange(pDX);

     DDX_Control(pDX, IDC_SCREEN, m_screen);
    }

    BEGIN_MESSAGE_MAP(CshowpicDlg, CDialog)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
     ON_BN_CLICKED(IDC_BUTTON1, &CshowpicDlg::OnBnClickedButton1)
     ON_BN_CLICKED(IDC_BUTTON2, &CshowpicDlg::OnBnClickedButton2)
     ON_WM_TIMER()
    END_MESSAGE_MAP()


    // CshowpicDlg 消息处理程序

    BOOL CshowpicDlg::OnInitDialog()
    {
     CDialog::OnInitDialog();

     // 将“关于...”菜单项添加到系统菜单中。

     // IDM_ABOUTBOX 必须在系统命令范围内。
     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     ASSERT(IDM_ABOUTBOX < 0xF000);

     CMenu* pSysMenu = GetSystemMenu(FALSE);
     if (pSysMenu != NULL)
     {
      CString strAboutMenu;
      strAboutMenu.LoadString(IDS_ABOUTBOX);
      if (!strAboutMenu.IsEmpty())
      {
       pSysMenu->AppendMenu(MF_SEPARATOR);
       pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
      }
     }

     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
     //  执行此操作
     SetIcon(m_hIcon, TRUE);   // 设置大图标
     SetIcon(m_hIcon, FALSE);  // 设置小图标

     // TODO: 在此添加额外的初始化代码

     m_screen.SetWindowPos(&CWnd::wndBottom,0,0,960,720, SWP_NOMOVE | SWP_SHOWWINDOW);
     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }

    void CshowpicDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
     {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
     }
     else
     {
      CDialog::OnSysCommand(nID, lParam);
     }
    }

    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。

    void CshowpicDlg::OnPaint()
    {
     if (IsIconic())
     {
      CPaintDC dc(this); // 用于绘制的设备上下文

      SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

      // 使图标在工作矩形中居中
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;

      // 绘制图标
      dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
      CDialog::OnPaint();
     }
    }

    //当用户拖动最小化窗口时系统调用此函数取得光标显示。
    //
    HCURSOR CshowpicDlg::OnQueryDragIcon()
    {
     return static_cast<HCURSOR>(m_hIcon);
    }
    BYTE *buf[6];
    CBitmap m_bitmap;
    void CshowpicDlg::OnBnClickedButton1()
    {
     // TODO: 在此添加控件通知处理程序代码
     for(int i=0;i<6;i++)
     {
      HBITMAP m_hBitmap;//位图句柄
      BITMAP bm;//存放位图信息的结构
      CString strFilename,str;
      CFileDialog openBox(TRUE,NULL,_T(""),OFN_HIDEREADONLY,_T("bmp(*.bmp)|*.bmp|ALLFiles(*.*)|*.*||"),NULL);
      openBox.m_ofn.lpstrTitle=_T("打开数据文件640*480_bmp");
      INT_PTR nResult = openBox.DoModal();
      // 如果文件打开则准备播放
      if (nResult == IDOK)
      {
       strFilename=openBox.GetPathName();
      }
      else
      {
       return;
      }
      strFilename.ReleaseBuffer();
      str =strFilename;
      m_hBitmap = (HBITMAP)::LoadImage(NULL,str,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);   //装载位图
      if(m_bitmap.m_hObject)
       m_bitmap.DeleteObject();

      m_bitmap.Attach(m_hBitmap);//将句柄与CBitmap关联起来
      m_bitmap.GetBitmap(&bm);
      int  height = bm.bmHeight;//图像的宽高
      int  width = bm.bmWidth;
      int  widthBytes=bm.bmWidthBytes;//图像一行数据所占的字节数
      
      int size=height*widthBytes;
      buf[i]=new BYTE[size];
      m_bitmap.GetBitmapBits(size,buf[i]);//得到RGB数据
     }
    }
    #include <ddraw.h>

    #pragma comment (lib,"ddraw.lib")
    #pragma comment (lib,"dxguid.lib")

    LPDIRECTDRAW         lpdd=NULL;
    LPDIRECTDRAW7        lpdd7=NULL;
    LPDIRECTDRAWSURFACE7 lpddsback;
    LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;
    LPDIRECTDRAWSURFACE7 lpddsmypage[6];
    LPDIRECTDRAWPALETTE  lpddpal=NULL;
    DDSURFACEDESC2       ddsd;
    LPDIRECTDRAWCLIPPER  lpDDClipper = NULL;
    //
    #define  _RGB32BIT(a,r,g,b)  ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
    //#define  SCREEN_WIDTH  640
    //#define  SCREEN_HEIGHT 480
    RECT rcRectSrc;
    RECT rcRectDest;
    int   index_y = 0, index_x = 0;
    int height,width,widthBytes;
    int R, G, B;
    int SCREEN_WIDTH,SCREEN_HEIGHT;
    HWND main_window_handle;
    void CshowpicDlg::OnBnClickedButton2()
    {
     // TODO: 在此添加控件通知处理程序代码
     height=width=widthBytes=0;
     main_window_handle = m_screen.GetSafeHwnd();
     if(DD_OK!=(DirectDrawCreate(NULL, &lpdd, NULL)))
     {
      return ;
     }
     //获取DIRECTDRAW7 接口
        if(DD_OK != (lpdd->QueryInterface(IID_IDirectDraw7,(LPVOID*)&lpdd7)))
     {
      return ;
     }

     // set the cooperative level for full-screen mode
     if(DD_OK != lpdd7->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL))
     {

      return ;
     }
     
     // set the display mode to 640x480x256
    #if 0 //设置分辨率
        if(DD_OK!=(lpdd7->SetDisplayMode(800,600,32,0,0)))
     {  
      AfxMessageBox("dsf");
      return ;
     }
    #endif
     // clear ddsd and set size
     memset(&ddsd,0,sizeof(ddsd));
     ddsd.dwSize = sizeof(ddsd);
     
     // enable valid fields
     ddsd.dwFlags=DDSD_CAPS;
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
     // create the primary surface
     
     /* 
     ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
     if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback)))
     {
      return -1;
     }
     */
     
     if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)))
     {
      return ;
     }
     
     // 创建裁剪器
     if (FAILED(lpdd7->CreateClipper(0, &lpDDClipper, NULL)))
      return ;
     // 与窗口工作区关联

     if (FAILED(lpDDClipper->SetHWnd(0, main_window_handle)))
     {
      lpDDClipper->Release();
      return ;
     }
     
     if (FAILED(lpddsprimary->SetClipper(lpDDClipper)))
     {
      lpDDClipper->Release();
      return ;
     }
     {
      SCREEN_WIDTH = 640 ;SCREEN_HEIGHT = 480;
     }

     //
     memset(&ddsd,0,sizeof(ddsd));
     ddsd.dwSize = sizeof(ddsd);
     
     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
     ddsd.dwWidth = SCREEN_WIDTH;
     ddsd.dwHeight = SCREEN_HEIGHT;
     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
     //
     
        SetTimer(1,1000,NULL);
     return; //执行成功
    }

    int index=0;
    void CshowpicDlg::OnTimer(UINT_PTR nIDEvent)
    {
     // TODO: 在此添加消息处理程序代码和/或调用默认值
     int tmp = 0;
        for(int i=0;i<6;i++)
     {
      if(DD_OK!=(lpdd7->CreateSurface(&ddsd, &lpddsmypage[i], NULL)))
      {
       return ;
      }

      POINT p;
      
      p.x = 0; p.y = 0;
      m_screen.ClientToScreen(&p);
      tmp = (i+index)%6;
     // m_screen.GetClientRect(&rcRectDest);
            if(i==5)
          {rcRectDest.left = 0;  rcRectDest.top=0;  rcRectDest.right = 640;  rcRectDest.bottom = 480;}
      else if(i==4)
       {rcRectDest.left = 640;  rcRectDest.top=0;  rcRectDest.right = 960;  rcRectDest.bottom = 240;}
      else if(i==3)
       {rcRectDest.left = 640;  rcRectDest.top=240;  rcRectDest.right = 960;  rcRectDest.bottom = 480;}
      else if(i==2)
       {rcRectDest.left = 640;  rcRectDest.top=480;  rcRectDest.right = 960;  rcRectDest.bottom = 720;}
      else if(i==1)
       {rcRectDest.left = 320;  rcRectDest.top=480;  rcRectDest.right = 640;  rcRectDest.bottom = 720;}
      else if(i==0)
       {rcRectDest.left = 0;  rcRectDest.top=480;  rcRectDest.right = 320;  rcRectDest.bottom = 720;}

      OffsetRect(&rcRectDest, p.x, p.y);
      
      SetRect(&rcRectSrc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
      /////////////////////////////////////////////////////////////


      if(DD_OK != lpddsmypage[i]->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR,NULL))
      {
       return ;
      }
      
      DWORD *bmp_buffer = (DWORD *)ddsd.lpSurface;
      
      memcpy(bmp_buffer,buf[tmp],SCREEN_WIDTH*SCREEN_HEIGHT*4);

      if(DD_OK != lpddsmypage[i]->Unlock(NULL))
      {
       return ;
      }
      if(DD_OK != lpddsprimary->Blt( &rcRectDest, lpddsmypage[i], &rcRectSrc, DDBLT_WAIT, NULL))
      {
       return ;
      }
      if(lpddsmypage)
      {
       lpddsmypage[i]->Release();
       lpddsmypage[i]=NULL;
      }
     }
     index++;
     CDialog::OnTimer(nIDEvent);
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    MSSQL中with(nolock)的用法
    google reader 使用快捷键
    HTML中em标签的用法
    js正则表达式
    C#中lock关键字的用法
    面试反思
    关于IE6.7.8.FF兼容的问题
    C#中DateTime.Now.Ticks的用法和说明
    JS中eval的用法
    这两天面试时不会的笔试题
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706726.html
Copyright © 2011-2022 走看看