www.pudn.com > ViewerCarry.rar > ThumbViewerView.cpp
// ThumbViewerView.cpp : implementation of the CThumbViewerView class // #include "stdafx.h" #include "ThumbViewer.h" #include "MainFrm.h" #include "ThumbViewerDoc.h" #include "ThumbViewerView.h" #include "memdc.h" #include "BaseDef.h" #include "PhookUtil.h" #include#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif USERMSG g_UserMsg; ///////////////////////////////////////////////////////////////////////////// // CThumbViewerView IMPLEMENT_DYNCREATE(CThumbViewerView, CListView) BEGIN_MESSAGE_MAP(CThumbViewerView, CListView) //{{AFX_MSG_MAP(CThumbViewerView) ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged) ON_WM_ERASEBKGND() ON_COMMAND(ID_IMAGE_REMOVE, OnImageRemove) ON_COMMAND(ID_IMAGE_WITHDRAW, OnImageWithdraw) ON_COMMAND(ID_FILE_UPDATE, OnFileUpdate) ON_UPDATE_COMMAND_UI(ID_FILE_UPDATE, OnUpdateFileGray) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CThumbViewerView construction/destruction CThumbViewerView::CThumbViewerView() { // TODO: add construction code here m_bLoadThumbNailTerminate= false; m_bLoadThumbNailRunning= false; m_bResumeImageRuning = false; m_bResumeImageThread = false;//取消撤销线程标志 m_bUpdateFileRunning = false; m_bUpdateFileRunning = false;//上传线程标志 m_bRemoveImageRuning = false; m_bRemoveImageThread = false; // Initialize Thread Handle and Create Event Handle for controlling thread m_hLoadThumbNailThread = NULL; m_hUpdateFileThread = NULL; m_hRemoveImageThread = NULL; m_nSelectItem = -1; //m_nRemoveArray.clear(); //m_nCacelRemoveArray.clear(); for(int i=0;i IsKindOf(RUNTIME_CLASS(CThumbViewerDoc))); return (CThumbViewerDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CThumbViewerView message handlers BOOL CThumbViewerView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CListView::Create(lpszClassName, _T("ListView"), dwStyle|LVS_SHOWSELALWAYS|LVS_ALIGNTOP|LVS_ICON|LVS_SINGLESEL|LVS_AUTOARRANGE , rect, pParentWnd, nID, pContext); } unsigned __stdcall CThumbViewerView::LoadThumbNailThread(LPVOID lpParam) { CThumbViewerView* pView=(CThumbViewerView*)lpParam; CThumbViewerDoc* pDoc=pView->GetDocument(); CListCtrl& ListCtrl=pView->GetListCtrl(); CImageList* pImgList=&pView->m_ImageListThumb; // reset our image list for(int i=0; i GetImageCount(); i++) { pImgList->Remove(i); } // remove all items from list view ListCtrl.DeleteAllItems(); pImgList->SetImageCount(pDoc->m_vFileName.size()); TCHAR path[MAX_PATH]={0}; vector ::iterator iter; // Set redraw to FALSE to avoid flickering during adding new items ListCtrl.SetRedraw(FALSE); int nIndex=0; for(iter=pDoc->m_vFileName.begin(); iter!=pDoc->m_vFileName.end() && pView->m_bLoadThumbNailTerminate!=true; iter++, nIndex++) { //这里要去除文件路径,只保留文件名称 ListCtrl.InsertItem(nIndex, *iter, nIndex); } ListCtrl.SetRedraw(TRUE); ListCtrl.Invalidate(); // Create Brushes for Border and BackGround HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192)); HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));//背景是黑色 // Border Size RECT rcBorder; rcBorder.left=rcBorder.top=0; rcBorder.right=THUMBNAIL_WIDTH; rcBorder.bottom=THUMBNAIL_HEIGHT; const float fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH; int XDest, YDest, nDestWidth, nDestHeight; nIndex=0; //............................ for(iter=pDoc->m_vFilePath.begin(); iter!=pDoc->m_vFilePath.end() && pView->m_bLoadThumbNailTerminate!=true; iter++, nIndex++) { // Load Image File _stprintf(path, _T("%s"),*iter); int nImageType=pDoc->GetTypeFromFileName(path); if(nImageType==CXIMAGE_FORMAT_UNKNOWN) { continue; } CxImage image(path, nImageType); if(image.IsValid()==false) { continue; } // Calculate Rect to fit to canvas const float fImgRatio=(float)image.GetHeight()/image.GetWidth(); if(fImgRatio > fRatio) { nDestWidth=THUMBNAIL_HEIGHT/fImgRatio; XDest=(THUMBNAIL_WIDTH-nDestWidth)/2; YDest=0; nDestHeight=THUMBNAIL_HEIGHT; } else { XDest=0; nDestWidth=THUMBNAIL_WIDTH; nDestHeight=THUMBNAIL_WIDTH*fImgRatio; YDest=(THUMBNAIL_HEIGHT-nDestHeight)/2; } CClientDC cdc(pView);//定义pView为显示设备对象 HDC hDC=::CreateCompatibleDC(cdc.m_hDC);//建立与pView显示设备兼容的内存显示设备 //建立与pView显示设备兼容的位图 HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); //将位图选入到pView显示设备中 HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm); // Draw Background //使用背景色将位图清除干净 ::FillRect(hDC, &rcBorder, hBrushBk); // Draw Image //将图片画在pView内存显示设备上 image.Stretch(hDC, XDest, YDest, nDestWidth, nDestHeight); // Draw Border //在内存显示设备上画边框 ::FrameRect(hDC, &rcBorder, hBrushBorder); //将位图图像显示到pView显示设备上 SelectObject(hDC, pOldBitmapImage); // Attach to Bitmap and Replace image in CImageList CBitmap bitmap; bitmap.Attach(bm);//将位图贴到ImageList控件上 pImgList->Replace(nIndex, &bitmap, NULL); // Redraw only a current item for removing flickering and fast speed. ListCtrl.RedrawItems(nIndex, nIndex); // Release used DC and Object DeleteDC(hDC); DeleteObject(bm); } DeleteObject(hBrushBorder); DeleteObject(hBrushBk); ListCtrl.Invalidate(); pView->m_bLoadThumbNailRunning=false; pView->m_bLoadThumbNailTerminate=false; _endthreadex( 0 ); return 0; } void CThumbViewerView::LoadThumbImages() { CThumbViewerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CListCtrl& ListCtrl=GetListCtrl(); //另启一个线程显示缩略图 TerminateLoadThumbNailThread(); m_hLoadThumbNailThread = (HANDLE)_beginthreadex(NULL,0, LoadThumbNailThread,(LPVOID)this,0/* CREATE_SUSPENDED*/,&m_dwLoadThumbNailThreadID); m_bLoadThumbNailRunning=true; } void CThumbViewerView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here CThumbViewerDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //以成员变量的形式记录下每次改变的索引值 m_nSelectItem=-1; m_nSelectItem = pNMListView->iItem; pDoc->SelectItem(pNMListView->iItem); *pResult = 0; } BOOL CThumbViewerView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return CListView::OnEraseBkgnd(pDC); } void CThumbViewerView::OnImageRemove() { // TODO: Add your command handler code here //从缩略框移除图片,并从vector中移除此图片 if(-1 == m_nSelectItem) { return ; } //从View中移除图片..... if(-1 != m_nSelectItem) { RemoveSelectItem(m_nSelectItem); } //将要删除的索引值记录到数组中...... int removeFlag=0; if(removeFlag <= 0) { if(m_nRemove < MAX_ARRAY_NUM) { m_nRemoveArray[++m_nRemove]=m_nSelectItem; } else { AfxMessageBox("您一次选择的文件太多"); } } /* for(int i=1;i<=m_nCacelRemove;i++) { if(m_nCacelRemoveArray[i] == m_nSelectItem) { m_nCacelRemoveArray[i]=-1; } }//end for */ } void CThumbViewerView::RemoveSelectItem(int nIndex) { if(true == m_bLoadThumbNailRunning) { AfxMessageBox("请载入图片,或者等待刷新完毕后在使用移除图片功能!"); return ; } TerminateRemoveImageThread(); this->m_nRemoveImage = nIndex; m_hRemoveImageThread = (HANDLE)_beginthreadex(NULL,0, RemoveSelectImageThread,(LPVOID)this,0/* CREATE_SUSPENDED*/,&m_dwRemoveImageThreadID); this->m_bRemoveImageRuning = true; } unsigned __stdcall CThumbViewerView::RemoveSelectImageThread(LPVOID lpParam) { //从CImageList中删除项目 CThumbViewerView* pView=(CThumbViewerView*)lpParam; CThumbViewerDoc* pDoc=pView->GetDocument(); int nIndex = pView->GetRemoveImageIndex(); CListCtrl& ListCtrl=pView->GetListCtrl(); CImageList* pImgList=&pView->m_ImageListThumb; //vector ::iterator iter; // Create Brushes for Border and BackGround HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192)); HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));//背景是黑色 // Border Size RECT rcBorder; rcBorder.left=rcBorder.top=0; rcBorder.right=THUMBNAIL_WIDTH_MASK; rcBorder.bottom=THUMBNAIL_HEIGHT_MASK; const float fRatio=(float)THUMBNAIL_HEIGHT_MASK/THUMBNAIL_WIDTH_MASK; int XDest, YDest, nDestWidth, nDestHeight; //Set redraw to FALSE to avoid flickering during adding new items //ListCtrl.SetRedraw(FALSE); // Load Image File //_stprintf(path, _T("%s"),PATH_REMOVE_BMP); //这里要写函数得到当前目录 CPhookUtil PhookUtil; CString sIconDir = PhookUtil.GetNowPath(); sIconDir = sIconDir + "\\" + "icon" + "\\" + PATH_REMOVE_BMP; TCHAR path[MAX_PATH]={0}; _stprintf(path, _T("%s"),sIconDir.GetBuffer(0)); int nImageType=pDoc->GetTypeFromFileName(path); CxImage image(path, nImageType); if(image.IsValid()==false) { return -1; } //Calculate Rect to fit to canvas const float fImgRatio=(float)image.GetHeight()/image.GetWidth(); if(fImgRatio > fRatio) { nDestWidth=THUMBNAIL_HEIGHT_MASK/fImgRatio; XDest=(THUMBNAIL_WIDTH_MASK-nDestWidth)/2; YDest=0; nDestHeight=THUMBNAIL_HEIGHT_MASK; } else { XDest=0; nDestWidth=THUMBNAIL_WIDTH_MASK; nDestHeight=THUMBNAIL_WIDTH_MASK*fImgRatio; YDest=(THUMBNAIL_HEIGHT_MASK-nDestHeight)/2; } CClientDC cdc(pView);//定义pView为显示设备对象 HDC hDC=::CreateCompatibleDC(cdc.m_hDC);//建立与pView显示设备兼容的内存显示设备 //建立与pView显示设备兼容的位图 HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMBNAIL_WIDTH_MASK, THUMBNAIL_HEIGHT_MASK); //将位图选入到pView显示设备中 HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm); // Draw Background //使用背景色将位图清除干净 ::FillRect(hDC, &rcBorder, hBrushBk); // Draw Image //将图片画在pView内存显示设备上 image.AlphaSet(100); image.Stretch(hDC, XDest, YDest, nDestWidth, nDestHeight); // Draw Border //在内存显示设备上画边框 ::FrameRect(hDC, &rcBorder, hBrushBorder); //将位图图像显示到pView显示设备上 SelectObject(hDC, pOldBitmapImage); // Attach to Bitmap and Replace image in CImageList CBitmap bitmap; bitmap.Attach(bm);//将位图贴到ImageList控件上 pImgList->Replace(nIndex, &bitmap, NULL); //这里需要再贴一张透明的图片在原始的图片上........... //pImgList->SetOverlayImage(nIndex,1); //CPoint myPoint(XDest,YDest); //pImgList->Draw((CDC*)&hDC, 0, myPoint, INDEXTOOVERLAYMASK(1)); // Redraw only a current item for removing flickering and fast speed. ListCtrl.RedrawItems(nIndex, nIndex); // Release used DC and Object DeleteDC(hDC); DeleteObject(bm); DeleteObject(hBrushBorder); DeleteObject(hBrushBk); //ListCtrl.Invalidate(); pView->m_bRemoveImageRuning = false; pView->m_bRemoveImageThread = false; _endthreadex(0); return 0; } //在图片取消上传后又恢复上传 void CThumbViewerView::CancelRemoveSelectItem(int nIndex) { if(true == m_bLoadThumbNailRunning) { AfxMessageBox("请载入图片,或者等待刷新完毕后在使用撤销移除的图片功能按钮!"); return ; } TerminateResumeImageThread(); this->m_nResumeImage=nIndex; m_hResumeImageThread = (HANDLE)_beginthreadex(NULL,0,ResumeSelectImageThread,(LPVOID)this,0/* CREATE_SUSPENDED*/,&m_dwResumeImageThreadID); this->m_bResumeImageRuning = true; } //恢复图片线程 unsigned __stdcall CThumbViewerView::ResumeSelectImageThread(LPVOID lpParam) { //从CImageList中恢复图片 CThumbViewerView* pView = (CThumbViewerView*)lpParam; CThumbViewerDoc* pDoc=pView->GetDocument(); int nIndex = pView->GetResumeImageIndex(); CListCtrl& ListCtrl=pView->GetListCtrl(); CImageList* pImgList=&pView->m_ImageListThumb; TCHAR path[MAX_PATH]={0}; vector ::iterator iterFilePath; //vector ::iterator iterFileName; // Create Brushes for Border and BackGround HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192)); HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));//背景是黑色 // Border Size RECT rcBorder; rcBorder.left=rcBorder.top=0; rcBorder.right=THUMBNAIL_WIDTH; rcBorder.bottom=THUMBNAIL_HEIGHT; const float fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH; int XDest, YDest, nDestWidth, nDestHeight; //Set redraw to FALSE to avoid flickering during adding new items //ListCtrl.SetRedraw(FALSE); // Load Image File //通过要恢复的索引找到图片的路径,从新载入图片 int nTmpIndex=0; for(iterFilePath=pDoc->m_vFilePath.begin(); iterFilePath!=pDoc->m_vFilePath.end(); iterFilePath++, nTmpIndex++) { if(nTmpIndex < nIndex) { continue; } else if(nTmpIndex == nIndex) { _stprintf(path, _T("%s"),*iterFilePath); break; } }//end for int nImageType=pDoc->GetTypeFromFileName(path); CxImage image(path, nImageType); if(image.IsValid()==false) { return -1; } //Calculate Rect to fit to canvas const float fImgRatio=(float)image.GetHeight()/image.GetWidth(); if(fImgRatio > fRatio) { nDestWidth=THUMBNAIL_HEIGHT/fImgRatio; XDest=(THUMBNAIL_WIDTH-nDestWidth)/2; YDest=0; nDestHeight=THUMBNAIL_HEIGHT; } else { XDest=0; nDestWidth=THUMBNAIL_WIDTH; nDestHeight=THUMBNAIL_WIDTH*fImgRatio; YDest=(THUMBNAIL_HEIGHT-nDestHeight)/2; } CClientDC cdc(pView);//定义pView为显示设备对象 HDC hDC=::CreateCompatibleDC(cdc.m_hDC);//建立与pView显示设备兼容的内存显示设备 //建立与pView显示设备兼容的位图 HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); //将位图选入到pView显示设备中 HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm); // Draw Background //使用背景色将位图清除干净 ::FillRect(hDC, &rcBorder, hBrushBk); // Draw Image //将图片画在pView内存显示设备上 image.Stretch(hDC, XDest, YDest, nDestWidth, nDestHeight); // Draw Border //在内存显示设备上画边框 ::FrameRect(hDC, &rcBorder, hBrushBorder); //将位图图像显示到pView显示设备上 SelectObject(hDC, pOldBitmapImage); // Attach to Bitmap and Replace image in CImageList CBitmap bitmap; bitmap.Attach(bm);//将位图贴到ImageList控件上 pImgList->Replace(nIndex, &bitmap, NULL); //pImgList->SetOverlayImage(nIndex,1); // Redraw only a current item for removing flickering and fast speed. ListCtrl.RedrawItems(nIndex, nIndex); // Release used DC and Object DeleteDC(hDC); DeleteObject(bm); DeleteObject(hBrushBorder); DeleteObject(hBrushBk); //ListCtrl.Invalidate(); pView->m_bResumeImageRuning = false; pView->m_bResumeImageThread = false; _endthreadex(0); return 0; } void CThumbViewerView::OnImageWithdraw() { // TODO: Add your command handler code here //从缩略框移除图片,并从vector中移除此图片 if(-1 == m_nSelectItem) { return ; } //从View中移除图片..... if(-1 != m_nSelectItem) { CancelRemoveSelectItem(m_nSelectItem); } //将撤销的索引值记录到数组中.... int cacelRemoveFlag=0; if(cacelRemoveFlag <= 0) { if(m_nCacelRemove < MAX_ARRAY_NUM) { m_nCacelRemoveArray[++m_nCacelRemove] = m_nSelectItem; } else { AfxMessageBox("您撤销次数太多"); } } /* for(int i=1;i<=m_nRemove;i++) { if(m_nRemoveArray[i] == m_nSelectItem) { m_nRemoveArray[i]=-1; } }//end for */ return; } void CThumbViewerView::OnFileUpdate() { //得到上传的文件列表 CThumbViewerDoc* pDoc=this->GetDocument(); pDoc->GetTakeNote(); if(1 == pDoc->UpdateFileisEmpty()) { AfxMessageBox(UPDATE_EMPTYFILE_SHOW); return; } //m_hUpdateFileThread 需要的是数组 //启动上传线程线程.... //vector ::iterator iter; //for(iter = pDoc->m_vFilePath.begin();iter!= pDoc->m_vFilePath.end();iter++) //{ // TerminateUpdateFileThread(); // m_hUpdateFileThread = (HANDLE)_beginthreadex(NULL,0, UpdateFileToServerThread,(LPVOID)iter,0/* CREATE_SUSPENDED*/,&m_dwUpdateFileThreadID); // Sleep(100);//以后将改为多线程管理同时传输,要改为2个线程同时传输 //}//end for //弹出对话框 //给对话框发送进度条初始化消息 if(true == m_bLoadThumbNailRunning) { AfxMessageBox("请等待图片载入完毕,再使用上传功能!"); return ; } m_hUpdateFileThread = (HANDLE)_beginthreadex(NULL,0, UpdateFileToServerThread,(LPVOID)this,0/* CREATE_SUSPENDED*/,&m_dwUpdateFileThreadID); this->m_bUpdateFileRunning = true; CDisplayTranProgDlg DisplayTranProgDlg; DisplayTranProgDlg.DoModal(); } //传输线程 unsigned __stdcall CThumbViewerView::UpdateFileToServerThread(LPVOID lpParam) { //根据路径读取文件 //socket连接到server,使用TCP协议传送文件..(这里需要自定义包的格式), //这里需要得到服务器的IP地址,端口,在程序中使用宏定义写死 //每个文件连接一次,这样可以做到随时取消传输 // CThumbViewerView* pView = (CThumbViewerView*)lpParam; CThumbViewerDoc* pDoc=pView->GetDocument(); vector ::iterator iterFilePath; vector ::iterator iterFileName; //连接服务器,发送服务器用户名密码,告诉服务器文件长度 CSocketSession ImageSocketSession; ImageSocketSession.initialize(); SOCKET sTcpSck = ImageSocketSession.TcpSocket(); if(ImageSocketSession.TcpConnect(SERVER_PORT,SERVER_IP) == -1)//连接到服务器 { CString sErr; sErr = "网络故障或是上传服务器没有开启"; AfxMessageBox(sErr); _endthreadex( 0 ); return -1; } int nImage=0; int nImageTotal = pDoc->m_sUpdateFileName.size(); for(iterFilePath=pDoc->m_sUpdateFilePath.begin(),iterFileName = pDoc->m_sUpdateFileName.begin(); iterFilePath!=pDoc->m_sUpdateFilePath.end(),iterFileName!=pDoc->m_sUpdateFileName.end(); iterFilePath++,iterFileName++) { //读取文件 CPhookImageOp *phookImageOp; phookImageOp = new CPhookImageOp; phookImageOp->OpenImage(*iterFilePath); int nFileLen = phookImageOp->GetImageLen(); phookImageOp->ReadImage(nFileLen); phookImageOp->CloseImage(); //发送用户报文 //nSendByte =ImageSocketSession.TcpSend(sTcpSck,pBuff+nTotalCount,MAX_SEND_COUNT); //模拟 memset((void *)&g_UserMsg,0,sizeof(USERMSG)); _sntprintf(g_UserMsg.szUserID,64,_T("%-64s"),"15858"); //strcpy(g_UserMsg.szUserID,"15858");//这里要在ACTIVEX控件中获取网页填入的用户ID,用户名 _sntprintf(g_UserMsg.szUserName,64,_T("%-64s"),"submergerock@163.com"); _sntprintf(g_UserMsg.szPassWord,64,_T("%-64s"),"123456"); _sntprintf(g_UserMsg.szImageLen,64,_T("%-64d"),nFileLen); TCHAR szTmpImageName[128]={0}; strncpy(szTmpImageName,iterFileName->GetBuffer(0),128); _sntprintf(g_UserMsg.szImageName,128,_T("%-128s"),szTmpImageName); _sntprintf(g_UserMsg.szImageRemark,1472,_T("%-1472s"),"@"); if((ImageSocketSession.TcpSend(sTcpSck,(char *)&g_UserMsg,MSG_PACKET_LEN)) == -1) { //_endthreadex( 0 ); return -1; } //发送文件 int nSendByte=0,nTotalCount=0; char *pBuff =(char*)phookImageOp->GetImageBuff(); while(nTotalCount < nFileLen) { nSendByte =ImageSocketSession.TcpSend(sTcpSck,pBuff+nTotalCount,MAX_SEND_COUNT); if(nSendByte == -1) { AfxMessageBox("不能发送包体"); return -1; } nTotalCount += nSendByte; }//end while delete phookImageOp; phookImageOp = NULL; //发送进度条显示消息 nImage++; char szMsg[256]={0}; _stprintf(szMsg,_T("一共传输%d个文件,已经发送了%d个文件,当前文件是%s"),nImage,nImageTotal,szTmpImageName); int nPercent = (nImage*100)/nImageTotal; ::PostMessage(g_hDlgWnd,WM_FILE_UPDATE,(WPARAM)szMsg,nPercent); }//end for //关闭连接 ImageSocketSession.TcpClose(sTcpSck); ImageSocketSession.destory(); pView->m_bRemoveImageRuning = false; pView->m_bRemoveImageThread = false; //发送消息改变 m_bRemoveImageRuning,m_bRemoveImageThread的值 _endthreadex( 0 );//会出现问题 return 0; } BOOL CThumbViewerView::TerminateLoadThumbNailThread() { if ( !m_bLoadThumbNailRunning ) { return TRUE; } m_bLoadThumbNailTerminate=true; for( ; ; ) { if ( ::WaitForSingleObject(m_hLoadThumbNailThread, 0) == WAIT_OBJECT_0 ) { break; } MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) break; } } ::CloseHandle(m_hLoadThumbNailThread); return TRUE; } //终止文件传输线程 BOOL CThumbViewerView::TerminateUpdateFileThread() { if ( !m_bUpdateFileRunning ) { return TRUE; } m_bUpdateFileThread=true; for( ; ; ) { if ( ::WaitForSingleObject(m_hUpdateFileThread, 0) == WAIT_OBJECT_0 ) { break; } MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) break; } } ::CloseHandle(m_hUpdateFileThread); return TRUE; } //终止恢复图片线程 BOOL CThumbViewerView::TerminateResumeImageThread() { if( !m_bResumeImageThread ) { return TRUE; } m_bResumeImageThread=true; for( ; ; ) { if ( ::WaitForSingleObject(m_hResumeImageThread, 0) == WAIT_OBJECT_0 ) { break; } MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { break; } } } ::CloseHandle(m_hResumeImageThread); return TRUE; } int CThumbViewerView::GetResumeImageIndex() { return m_nResumeImage; } BOOL CThumbViewerView::TerminateRemoveImageThread() { if ( !m_bRemoveImageThread ) { return TRUE; } m_bRemoveImageThread=true; for( ; ; ) { if ( ::WaitForSingleObject(m_hRemoveImageThread, 0) == WAIT_OBJECT_0 ) { break; } MSG msg; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { break; } } } ::CloseHandle(m_hRemoveImageThread); return TRUE; } int CThumbViewerView::GetRemoveImageIndex() { return m_nRemoveImage; } void CThumbViewerView::ClearCompArray() { for(int i=0;i Enable(TRUE); //pCmdUI->Checked(TRUE); }