我在一个对话框中利用MCIWnd在以一个静态控件作为播放窗口,另有打开(文件进行播放),停止,抓图按钮.现在播放的功能实现的差不多了,抓图部分还有很多问题,就是用鼠标在播放窗口中选取矩形范围,然后保存为bmp文件.我调用HBITMAP CopyClientRectToBitmap(HWND hWnd, LPRECT lpRect);函数,可是老出错.我想可能是LPRECT参数赋值有错,OnLButtonDown和OnLButtonUp得到的坐标有效吗,还需要进行转换吗.如果有其他思路,请提出来.
    也希望认真理解OnLButtonDown,OnLButtonUp,LPRECT,CopyClientRectToBitmap的用法,希望了解的朋友能指点一下,或者举些例子.
    本人之前没学过vc,却要用它来做设计,没办法,只能边做边解决问题,很简单的问题都搞不定,请大家多包涵,耐心点,尽量讲得详细点,有资料更好,谢谢!
    凡参与的朋友都欢迎!

解决方案 »

  1.   

    void CMCIWndTestDlg::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    SetCapture();
    CDialog::OnLButtonDown(nFlags, point);
        GetCursorPos(&pt1);
    ScreenToClient(&pt1);}void CMCIWndTestDlg::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default

    CDialog::OnLButtonUp(nFlags, point);
        GetCursorPos(&pt2);
    ScreenToClient(&pt2);
    OPENFILENAME ofn;
     TCHAR lpstrFilename[MAX_PATH]="屏幕截图文件.bmp";
     ZeroMemory(&ofn,sizeof(ofn));
     ofn.lStructSize=sizeof(OPENFILENAME);
     ofn.hwndOwner=this->m_hWnd;
     ofn.lpstrFilter="位图文件(.BMP)\0*.bmp";
         ofn.nMaxFile=MAX_PATH;
     ofn.lpstrFile=lpstrFilename;
     ofn.lpstrTitle="将屏幕截图文件另存为?";
         GetSaveFileName(&ofn);
     LPRECT rc=(CRect(pt1,pt2));
     
         HBITMAP hbitmap=CopyClientRectToBitmap(hMCIWnd,rc);
     
         if(!SaveBitmapToFile(hbitmap, ofn.lpstrFile))
     AfxMessageBox("文件保存出错!");
     ReleaseCapture();}
      

  2.   

    之前已经声明了pt1,pt2,一到调用SaveBitmapToFile(hbitmap, ofn.lpstrFile)时就出错了,我一步一步试过了
      

  3.   

    当avi文件播放的时候,对鼠标根本不响应,鼠标弹起的时候没有任何反应,而在播放区域外的地方都响应,所以就无法抓取播放的屏幕了,怎么修改?各位高手,都出点声吧.
      

  4.   

    我也来帮你顶顶!!!
    可惜我不行啊不然一定help you!!!
      

  5.   

    调用SaveBitmapToFile(hbitmap, ofn.lpstrFile)时报的什么错?
      

  6.   

    我也在用MCIWnd,有一些资料,你自己看吧。应用程序可以截获发生在主窗口内的鼠标消息,却无法截获发生在视频窗口内的鼠标消息,因为Windows已将视频窗口的鼠标消息处理函数封装在MCIWnd窗口类中。所以,为了截获发生在视频窗口内的鼠标信息,需要重新定义MCIWnd窗口消息处理函数。 
    //在头文件中加入:
    WNDPROC OldProc; //保存原映射函数
    LRESULT CALLBACK NewProc(HWND,UINT,WPARAM,LPARAM); //新映射函数//在cpp中适当地方加入下面的(其中m_VideoWnd是MCIWndCreate的返回值):
    /* 调用GetWindowLong函数得到m_VideoWnd窗口原消息处理函数的入口地址,
    并保存在OldProc中。*/
    OldProc=(WNDPROC) ::GetWindowLong(m_VideoWnd,GWL_WNDPROC);/* 调用SetWindowLong函数将m_VideoWnd窗口消息处理函数的入口地址改为NewProc */
    ::SetWindowLong(m_VideoWnd,GWL_WNDPROC,(LONG)NewProc);//NewProc的实现
    LRESULT CALLBACK NewProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

        if(message==WM_LBUTTONDOWN)  //鼠标左键被按下
        {
        }
        //如果不是鼠标左键按下消息,则调用原处理函数:
        return CallWindowProc(OldProc,hWnd,message,wParam,lParam);
    }
      

  7.   

    SaveBitmapToFile(hbitmap, ofn.lpstrFile)出错只能是两方面原因:
    1。hbitmap有问题
    2。ofn.lpstrFile不正确
    而现在,ofn.lpstrFile看起来是没问题的,于是要从hbitmap追起
      

  8.   


    int SaveBitmapToFile(HBITMAP hBitmap ,  
    LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄 
    { //lpFileName 为位图文件名 
    HDC hDC;  
    //设备描述表 
    int iBits;  
    //当前显示分辨率下每个像素所占字节数 
    WORD wBitCount;  
    //位图中每个像素所占字节数 
    //定义调色板大小, 位图中像素字节大小 , 
    位图文件大小 , 写入文件字节数 
    DWORD dwPaletteSize=0, 
    dwBmBitsSize, 
    dwDIBSize, dwWritten; 
    BITMAP Bitmap;  
    //位图属性结构 
    BITMAPFILEHEADER bmfHdr;  
    //位图文件头结构 
    BITMAPINFOHEADER bi;  
    //位图信息头结构  
    LPBITMAPINFOHEADER lpbi;  
    //指向位图信息头结构 
    HANDLE fh, hDib, hPal,hOldPal=NULL; 
    //定义文件,分配内存句柄,调色板句柄 
     
    //计算位图文件每个像素所占字节数 
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL); 
    iBits = GetDeviceCaps(hDC, BITSPIXEL) *  
    GetDeviceCaps(hDC, PLANES); 
    DeleteDC(hDC); 
    if (iBits 〈 = 1) 
    wBitCount = 1; 
    else if (iBits 〈 = 4) 
    wBitCount = 4; 
    else if (iBits 〈 = 8) 
    wBitCount = 8; 
    else if (iBits 〈 = 24) 
    wBitCount = 24; 
    //计算调色板大小 
    if (wBitCount 〈 = 8) 
    dwPaletteSize = (1 〈 〈 wBitCount) * 
    sizeof(RGBQUAD); 
     
    //设置位图信息头结构 
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); 
    bi.biSize = sizeof(BITMAPINFOHEADER); 
    bi.biWidth = Bitmap.bmWidth; 
    bi.biHeight = Bitmap.bmHeight; 
    bi.biPlanes = 1; 
    bi.biBitCount = wBitCount; 
    bi.biCompression = BI_RGB; 
    bi.biSizeImage = 0; 
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0; 
     
    dwBmBitsSize = ((Bitmap.bmWidth * 
    wBitCount+31)/32)* 4 
    *Bitmap.bmHeight ; 
    //为位图内容分配内存 
    hDib = GlobalAlloc(GHND,dwBmBitsSize+ 
    dwPaletteSize+sizeof(BITMAPINFOHEADER)); 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
    *lpbi = bi; 
    // 处理调色板  
    hPal = GetStockObject(DEFAULT_PALETTE); 
    if (hPal) 

    hDC = GetDC(NULL); 
    hOldPal = SelectPalette(hDC, hPal, FALSE); 
    RealizePalette(hDC); 

    // 获取该调色板下新的像素值 
    GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, 
    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) 
    +dwPaletteSize, 
    (BITMAPINFOHEADER *) 
    lpbi, DIB_RGB_COLORS); 
    //恢复调色板  
    if (hOldPal) 

    SelectPalette(hDC, hOldPal, TRUE); 
    RealizePalette(hDC); 
    ReleaseDC(NULL, hDC); 

    //创建位图文件  
    fh = CreateFile(lpFileName, GENERIC_WRITE,  
    0, NULL, CREATE_ALWAYS, 
    FILE_ATTRIBUTE_NORMAL | FILE_ 
    FLAG_SEQUENTIAL_SCAN, NULL); 
    if (fh == INVALID_HANDLE_VALUE) 
    return FALSE; 
    // 设置位图文件头 
    bmfHdr.bfType = 0x4D42; // "BM" 
    dwDIBSize = sizeof(BITMAPFILEHEADER)  
    + sizeof(BITMAPINFOHEADER) 
    + dwPaletteSize + dwBmBitsSize;  
    bmfHdr.bfSize = dwDIBSize; 
    bmfHdr.bfReserved1 = 0; 
    bmfHdr.bfReserved2 = 0; 
    bmfHdr.bfOffBits = (DWORD)sizeof 
    (BITMAPFILEHEADER)  
    + (DWORD)sizeof(BITMAPINFOHEADER) 
    + dwPaletteSize; 
    // 写入位图文件头 
    WriteFile(fh, (LPSTR)&bmfHdr, sizeof 
    (BITMAPFILEHEADER), &dwWritten, NULL); 
    // 写入位图文件其余内容 
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize,  
    &dwWritten, NULL); 
    //清除  
    GlobalUnlock(hDib); 
    GlobalFree(hDib); 
    CloseHandle(fh); 

      

  9.   

    To NOMADBLUE:
    非常感谢你的帮助,我也希望尽快解决问题.结贴时一定多给你点分,再次感谢!
      

  10.   

    还有rolen,你的资料也很有用,谢谢!
      

  11.   

    rolen:那些东东往哪添啊,我的程序里面都没有MCIWnd类,我是添加了一个VFW32.lib文件就可以实现播放了.刚才我在其他的.cpp文件里面添加那些东西,老出错,SetWindowLong好像是非法调用,我不知道怎么解决这个问题.
        会的人请指点一下,出点声吧!
      

  12.   

    如何得到鼠标在MCIWnd播放窗口内(不包括进度条)的坐标?
      

  13.   

    SetWindowLong是API函数,调用应该没有问题的。如果还出错,就查MSDN,看看需要包含哪些头文件。你可以在MCIWndCreate调用后加入下面的语句:
    OldProc=(WNDPROC) ::GetWindowLong(m_VideoWnd,GWL_WNDPROC);
    ::SetWindowLong(m_VideoWnd,GWL_WNDPROC,(LONG)NewProc);
    这样,就截获发生在视频窗口内的鼠标信息了。你再试试看
      

  14.   

    我试验了,可以用。获得鼠标坐标代码如下:
    LRESULT CALLBACK NewProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

        if(message==WM_LBUTTONDOWN)
    {
    int xPos = LOWORD(lParam);
    int yPos = HIWORD(lParam);
    char buf[40];
    sprintf(buf, "x=%d  y=%d", xPos,yPos);
    MessageBox(NULL, buf, "坐标", MB_OK);
    }
        return CallWindowProc(OldProc,hWnd,message,wParam,lParam);
    }
    不过,这个坐标是视频窗口的相对坐标
      

  15.   

    谢谢rolen
    我找遍了论坛,也不知道头文件是啥
    是不是不需要头文件的啊?
    呵呵,我都傻了自己继续顶
      

  16.   

    GetWindowLong和SetWindowLong函数好像不用包含新的头文件。
    是不是你用的时候参数错了?
    把你的SetWindowLong调用代码贴出来看看
      

  17.   

    ::SetWindowLong(hMCIWnd,GWL_WNDPROC,(LONG)NewProc);
    我照搬了,就这一行,我把它放在CALLBACK NewProc的后面了
    hMCIWnd是avi播放窗口句柄
      

  18.   

    调用没有错误。
    是不是NewProc声明的地方不对?试试将声明语句
    WNDPROC OldProc;
    LRESULT CALLBACK NewProc(HWND,UINT,WPARAM,LPARAM); 
    都放到cpp里面。或者把你程序的提示错误贴出来,我看看能不能帮你解决。
      

  19.   

    rolen,我给你留言了,看看收到没.
    近期结贴.
    谢谢各位回帖的人!