Q 请教高手,图形对话框的问题
T 我做了一个图象的界面,对话框的,在OnPaint中 画上背景图案,然后用Invalidate 方法刷新每个控件,但是控件并没有完全显示出来,特别是CCtrlList 等控件,滚动条有时候显示不出来,CEdit控件边上的3d效果也出不来,这是怎么了?哪位大虾指点指点!
A class AFX_EXT_CLASS CBackgroundManager 
{
public:
 CBackgroundManager();
 virtual ~CBackgroundManager();

enum BackgroundLocation
 {
  BACKGR_TILE,
  BACKGR_TOPLEFT,
  BACKGR_TOPRIGHT,
  BACKGR_BOTTOMLEFT,
  BACKGR_BOTTOMRIGHT,
 };
protected:
 HBITMAP    m_hBkgrBitmap;
 CSize    m_sizeBkgrBitmap;
 CBrush    m_brBkgr;
 BackgroundLocation m_BkgrLocation;
 BOOL    m_bAutoDestroyBmp;
 CWnd* m_pWnd;
public:
 void Init(CWnd* pWnd){m_pWnd=pWnd;}
 void SetBackgroundColor (COLORREF color, BOOL bRepaint = TRUE);
 void SetBackgroundImage (HBITMAP hBitmap,
       BackgroundLocation location = BACKGR_TILE,
       BOOL bAutoDestroy = TRUE,
       BOOL bRepaint = TRUE);
 BOOL SetBackgroundImage (UINT uiBmpResId,
       BackgroundLocation location = BACKGR_TILE,
       BOOL bRepaint = TRUE);
 BOOL HandleOnEraseBackground(CDC* pDC);
 void HandleOnDestroy();
};

CBackgroundManager::CBackgroundManager()
{
 m_hBkgrBitmap = NULL;
 m_sizeBkgrBitmap = CSize (0, 0);
 m_BkgrLocation = (BackgroundLocation) -1;
 m_bAutoDestroyBmp = FALSE;
 m_pWnd=NULL;
}

CBackgroundManager::~CBackgroundManager()
{

}
//*************************************************************************************
void CBackgroundManager::SetBackgroundColor (COLORREF color, BOOL bRepaint)
{
 if (m_brBkgr.GetSafeHandle () != NULL)
 {
  m_brBkgr.DeleteObject ();
 }

if (color != (COLORREF)-1)
 {
  m_brBkgr.CreateSolidBrush (color);
 }

if (bRepaint && m_pWnd->GetSafeHwnd () != NULL)
 {
  m_pWnd->Invalidate ();
  m_pWnd->UpdateWindow ();
 }
}
//*************************************************************************************
void CBackgroundManager::SetBackgroundImage (HBITMAP hBitmap,
        BackgroundLocation location,
        BOOL bAutoDestroy,
        BOOL bRepaint)
{
 if (m_bAutoDestroyBmp && m_hBkgrBitmap != NULL)
 {
  ::DeleteObject (m_hBkgrBitmap);
 }

m_hBkgrBitmap = hBitmap;
 m_BkgrLocation = location;
 m_bAutoDestroyBmp = bAutoDestroy;

if (hBitmap != NULL)
 {
  BITMAP bmp;
  ::GetObject (hBitmap, sizeof (BITMAP), (LPVOID) &bmp);

m_sizeBkgrBitmap = CSize (bmp.bmWidth, bmp.bmHeight);
 }
 else
 {
  m_sizeBkgrBitmap = CSize (0, 0);
 }

if (bRepaint && m_pWnd->GetSafeHwnd () != NULL)
 {
  m_pWnd->Invalidate ();
  m_pWnd->UpdateWindow ();
 }
}
//*************************************************************************************
BOOL CBackgroundManager::SetBackgroundImage (UINT uiBmpResId,
         BackgroundLocation location,
         BOOL bRepaint)
{
 HBITMAP hBitmap = NULL;

if (uiBmpResId != 0)
 {
  hBitmap = ::LoadBitmap (AfxGetResourceHandle (),
          MAKEINTRESOURCE (uiBmpResId));
  if (hBitmap == NULL)
  {
   ASSERT (FALSE);
   return FALSE;
  }
 }

SetBackgroundImage (hBitmap, location, TRUE /* Autodestroy */, bRepaint);
 return TRUE;
}
//virtual
BOOL CBackgroundManager::HandleOnEraseBackground(CDC* pDC)
{
 if (m_brBkgr.GetSafeHandle () == NULL && m_hBkgrBitmap == NULL)
 {
  return FALSE;
 }

ASSERT_VALID (pDC);

CRect rectClient;
 m_pWnd->GetClientRect (rectClient);

if (m_BkgrLocation != BACKGR_TILE || m_hBkgrBitmap == NULL)
 {
  if (m_brBkgr.GetSafeHandle () != NULL)
  {
   pDC->FillRect (rectClient, &m_brBkgr);
  }
  else
  {
   return FALSE;
  }
 }

if (m_hBkgrBitmap == NULL)
 {
  return TRUE;
 }

ASSERT (m_sizeBkgrBitmap != CSize (0, 0));

if (m_BkgrLocation != BACKGR_TILE)
 {
  CPoint ptImage = rectClient.TopLeft ();

switch (m_BkgrLocation)
  {
  case BACKGR_TOPLEFT:
   break;

case BACKGR_TOPRIGHT:
   ptImage.x = rectClient.right - m_sizeBkgrBitmap.cx;
   break;

case BACKGR_BOTTOMLEFT:
   ptImage.y = rectClient.bottom - m_sizeBkgrBitmap.cy;
   break;

case BACKGR_BOTTOMRIGHT:
   ptImage.x = rectClient.right - m_sizeBkgrBitmap.cx;
   ptImage.y = rectClient.bottom - m_sizeBkgrBitmap.cy;
   break;
  }

pDC->DrawState (ptImage, m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
 }
 else
 {
  // Tile background image:
  for (int x = rectClient.left; x < rectClient.Width (); x += m_sizeBkgrBitmap.cx)
  {
   for (int y = rectClient.top; y < rectClient.Height (); y += m_sizeBkgrBitmap.cy)
   {
    pDC->DrawState (CPoint (x, y), m_sizeBkgrBitmap, m_hBkgrBitmap, DSS_NORMAL);
   }
  }
 }

return TRUE;
}
void CBackgroundManager::HandleOnDestroy()
{
 if (m_bAutoDestroyBmp && m_hBkgrBitmap != NULL)
 {
  ::DeleteObject (m_hBkgrBitmap);
  m_hBkgrBitmap = NULL;
 }
}

cann HandleOnEraseBackground when handling WM_ERASEBKGND
cann HandleOnDestroywhen handling WM_DESTROY

Q 菜单是在哪里换的?
T  
A 在子框架激活的时候替换的,去看MFC源代码

CDocument has a vertual method to return the default menu handle
CDocument::GetDefaultMenu
override this function to provide your own menu

MSDN
Knowledge Base

How to Use Multiple Menus in MFC App That Uses GetDefaultMenu
PSS ID Number: Q145857

http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B145857

错了,还有CDocTemplate
替换CDocTemplate::m_hMenuShared

Q 如何作类似于ACDSee那样的缩略图显示. 
T 如何作类似于ACDSee那样的缩略图显示.
A BEGIN_MESSAGE_MAP(CImagePage, CPropertyPage)
 ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST_PREVIEW, OnCustomDraw)
END_MESSAGE_MAP()

void CImagePage::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
 // TODO: Add your control notification handler code here
 LPNMLVCUSTOMDRAW pnmCustDraw = (LPNMLVCUSTOMDRAW)pNMHDR;
 switch(pnmCustDraw->nmcd.dwDrawStage){
 case CDDS_PREPAINT:
  *pResult = CDRF_NOTIFYITEMDRAW ;break;
 case CDDS_ITEMPREPAINT:
  *pResult = CDRF_NOTIFYPOSTPAINT ;break;
 case CDDS_ITEMPOSTPAINT:{
  int iItem=pnmCustDraw->nmcd.dwItemSpec;
  CDC dc;
  dc.Attach(pnmCustDraw->nmcd.hdc);
  HICON hi=GetIconFromFile(m_strImageFile,iItem);
  m_pic.CreateFromIcon(hi);DestroyIcon(hi);
  CRect rectDest;
  m_wndImgPrvwList.GetItemRect(iItem,rectDest,LVIR_ICON);
//   int nSaveDC=dc.SaveDC();
//   dc.SetMapMode(MM_HIMETRIC);
  dc.DPtoLP(rectDest);
  g_RectSwapTopBottom(rectDest);
  m_pic.Render(&dc,&rectDest);
//   dc.RestoreDC(nSaveDC);  
  dc.Detach();
  *pResult = CDRF_DODEFAULT;
  break;
  }
 default:
  *pResult = CDRF_DODEFAULT;
  break;
 }
}
HICON GetIconFromFile   ( CString strFileName, int nIndex )
{
 return ExtractIcon(AfxGetInstanceHandle(),strFileName, nIndex);
}

Q 对话框resize时,如何保证其有一个最小的rect范围?。。。。。。
T 2)再就是无模式对话框在ModifyStyleEx(0, WS_EX_TOOLWINDOW);后,其标题条变窄了,而且下面有一窄条,随机出现客户区一部分位图的图像,是怎么回事?
---------------------------------------
3)还是resize的问题,里面有一个list,几个btn,当resize时,如果list的rect消失了,那再放大时,其下面的btn就被覆盖(一部分显示,一部分不显示);如果resize过程中,list不消失,则一切正常,不知道为什么?
A 1 WM_GETMINMAXINFO
2 默认行为
3 默认行为

没有加消息映射的问题,去加一个到其他不是对话框的窗口,把消息映射复制过来

Q 为什么编辑框中ctrl+c / ctrl+v没法用?
T 我在一个单文档的程序中使用了ie风格的工具栏(IDR_MAINFRAME),上面布置了多个编辑控件,可是发现没办法使用ctrl+c和ctrl+v。具体来说,就是在下面的view区中copy了一段文字,想paste到上面的编辑框,但是按了这个快捷键后,却粘贴到view区中去了。为什么不能粘贴到我光标所在的编辑框中呢?我的view是从richeditview中继承过来的。请各位大侠指点,分不够可以另开贴加分。
A Knowledge Base 
Q145616
HOWTO: How to Enable Edit Menu Commands for Edit Controls

On a CDialog or other window that has no edit menu options for cutting, copying, and pasting, CEdit controls handle these functions through the normal Windows accelerator processing (CTRL+X,V,C, or the SHIFT-DELETE, SHIFT-INSERT, CTRL-INSERT, CTRL-DELETE, and so on keys). However, in a typical MDI or SDI application, these options are disabled.

This is due to the default implementation for menu handlers and accelerator keys that AppWizard adds to your application to handle these functions. These menu handlers get the accelerator keystrokes instead of your edit control. This article shows you how to implement the edit control's clipboard functions on a CFormView-derived form

Q 请教,如何实现多行文本在一个指定RECT内的绘制?
T 向各位高手请教,如何实现多行文本在一个指定RECT内的绘制,并能够实现文本在水平及垂直方向上的对齐?
A http://search.csdn.net/expert/topic/50/5001/2002/1/10/469317.htm

void CFlxRptText::Draw(Gdiplus::Graphics* pGraphics,CDrawContext* pDrawContext,CFlexReportView* pView)
{
 //draw text
 CRect position=GetPosition();
 _bstr_t bstrText;
 _bstr_t bstrTag=(*this)->GettagName();
 if(bstrTag==CFlxRptObj::GetObjTagName(TextObj)){
  bstrText=GetAttributeString("Text");
 }
 else
  bstrText=GetAttributeString("Data");
 
 if(bstrText.length()>0){
  _bstr_t bstrFontName=GetAttributeString("Font");
  int  nFontSize=GetAttributeLong("nFontSize");
  int  nFontStyle=GetAttributeLong("nFontStyle");
  if(nFontSize==0)
   nFontSize=pDrawContext->nPageFontSize;
 
  Gdiplus::FontFamily  fontFamilyText(bstrFontName);
  Gdiplus::Font fontText(&fontFamilyText,(Gdiplus::REAL)nFontSize,nFontStyle,Gdiplus::UnitPoint);
  Gdiplus::Font *pFontText=&fontText;

if(bstrFontName==_bstr_t("Default")||pFontText->GetLastStatus()!=Gdiplus::Ok){
   pFontText=pDrawContext->pFontDefault;
  }
  ;
 
  Gdiplus::RectF rectF=CGlobal::g_GdiplusRectFFromRect(position);
  int nHorizontalAlign=GetAttributeLong("HorizontalAlign");
  int nVerticalAlign=GetAttributeLong("VerticalAlign");
  switch(nHorizontalAlign){
  default:
  case 0:
   pDrawContext->StringFormatDefault.SetAlignment( Gdiplus::StringAlignmentNear);break;
  case 1:
   pDrawContext->StringFormatDefault.SetAlignment(Gdiplus::StringAlignmentCenter);break;
  case 2:
   pDrawContext->StringFormatDefault.SetAlignment( Gdiplus::StringAlignmentFar );break;
  }
  switch(nVerticalAlign){
  default:
  case 0:
   pDrawContext->StringFormatDefault.SetLineAlignment(Gdiplus:: StringAlignmentNear);break;
  case 1:
   pDrawContext->StringFormatDefault.SetLineAlignment(Gdiplus::StringAlignmentCenter);break;
  case 2:
   pDrawContext->StringFormatDefault.SetLineAlignment(Gdiplus:: StringAlignmentFar );break;
  }
  pGraphics->DrawString(bstrText, -1, pFontText, rectF, &pDrawContext->StringFormatDefault, &pDrawContext->BrushText);
 }
 enum enumBorder{Border_Top,Border_Bottom,Border_Left,Border_Right,Border_Max};
 int nBorderThickness=GetAttributeLong("BorderThickness");
 int nLineStyle[Border_Max];
 Gdiplus::Point ptStart[Border_Max];
 Gdiplus::Point ptEnd[Border_Max];

nLineStyle[Border_Top]=GetAttributeLong("TopLineStyle");
 nLineStyle[Border_Bottom]=GetAttributeLong("BottomLineStyle");
 nLineStyle[Border_Left]=GetAttributeLong("LeftLineStyle");
 nLineStyle[Border_Right]=GetAttributeLong("RightLineStyle");

ptStart[Border_Top].X=position.left;
 ptStart[Border_Top].Y=position.top;
 ptEnd[Border_Top].X=position.right;
 ptEnd[Border_Top].Y=position.top;
 ptStart[Border_Bottom].X=position.left;
 ptStart[Border_Bottom].Y=position.bottom;
 ptEnd[Border_Bottom].X=position.right;
 ptEnd[Border_Bottom].Y=position.bottom;
 ptStart[Border_Left].X=position.left;
 ptStart[Border_Left].Y=position.top;
 ptEnd[Border_Left].X=position.left;
 ptEnd[Border_Left].Y=position.bottom;
 ptStart[Border_Right].X=position.right;
 ptStart[Border_Right].Y=position.top;
 ptEnd[Border_Right].X=position.right;
 ptEnd[Border_Right].Y=position.bottom;

for(int j=0;j<Border_Max;j++){
  switch(nLineStyle[j]){
  default:
   case 0://noline
    pDrawContext->pPenCur=&pDrawContext->penDotted;break;
   case 1:
    pDrawContext->pPenCur=&pDrawContext->penSingle;break;
   case 2:
    pDrawContext->pPenCur=&pDrawContext->penDouble;break;
  }
  pDrawContext->pPenCur->SetWidth((float)(nBorderThickness==0?1:nBorderThickness));
  pGraphics->DrawLine(pDrawContext->pPenCur,ptStart[j],ptEnd[j]);
 }

}

Command what is yours
Conquer what is not

http://www.csdn.net/develop/author/netauthor/jiangsheng/

Q 高分求解,与打印有关。。多谢
T
本人在开发虚似打印机时,遇到一个问题,要大家帮忙先谢一下:

本人的打印是从win2kddk的OEMDLL下面的oemuni下面的例子改编过来的

问题是:
1、为什么在打印时从内存中取出来的BMP文件会掉色,即红色的会转为兰色,
兰色转为红色

而黑色就成了白色,

所以当打印表格(是黑边框时就打不出来,但黑文字能打出来)不知何解。。

多谢。。

A http://blog.joycode.com/jiangsheng/posts/3579.aspx
Q 多个按钮共享Clicked事件后如何区分是点了哪一个按钮?
T
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton)
ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton)

在OnBnClickedButton中如何区分点了button1还是button4?

A 判断CWnd::GetCurrentMessage获得的消息的wParam
Q 如何给button改变颜色??
T  
A
绘制有纹理的背景的应用程序 (jiangsheng翻译)
http://www.csdn.net/develop/read_article.asp?id=9603
Q 有关属性页改名的问题!!
T   我用CPropertySheet创建属性页,用的CPropertyPage对象只有一个,也就是每个属性页的内容一样.
  想在的问题是:这样每个属性页的标题都是一样的,是对话框的标题!怎样动态的改变这个标题,使每个属性页的标签的名称都不同??
A >怎样动态的改变这个标题,使每个属性页的标签的名称都不同??
什么时候改?CPropertySheet创建之前/属性页激活之后?
如果是前者的话,修改CPropertySheet::m_psh
如果是后者的话,重载CPropertyPage::OnSetActive,
用GetParent()返回PropertySheet指针,然后SetWindowText

In some function of your page
CPropertyShee* pSheet=Parent();
CTabCtrl * pCtrl = pSheet->GetTabControl();
TCITEM tci;
tci.mask = TCIF_TEXT;
tci.pszText = "新标题";
pCtrl->SetItem(0,&tc); //change the title of page 1

Q 请教:dlg中有一个edit编辑框,用domodal(),如果用回车的话会推出对话框,why??? 
T 如何使它不这样啊?????
A
ES_WANTRETURN   Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiple-line edit control in a dialog box. Without this style, pressing the ENTER key has the same effect as pressing the dialog box’s default pushbutton. This style has no effect on a single-line edit control.

void CTabDialog::OnOK()
 {
    OnNextPrevField(ID_NEXT_FIELD);
 }
 
 /
 // Go to next or previous field
 //
 BOOL CTabDialog::OnNextPrevField(UINT nCmdID)
 {
    CWnd* pWnd = CWnd::GetFocus();
    if (m_bRandomTabOrder) {
       static int controls[] = { IDC_EDIT1,
          IDC_EDIT2, IDC_EDIT3, IDC_COMBO1, ID_CHANGE_TABS, IDOK, IDCANCEL };
       const NCONTROLS = sizeof(controls)/sizeof(int);
 
       // Select a random control that's different from the current one.
       int nIDCtrl;
       while ((nIDCtrl = controls[rand() % NCONTROLS]) == pWnd->GetDlgCtrlID())
          ; // same as current, try another
       pWnd = GetDlgItem(nIDCtrl);
 
    } else
       // Normal next/prev using dialog's TAB order.
       pWnd = GetNextDlgTabItem(pWnd, nCmdID==ID_PREV_FIELD);
 
    ASSERT(pWnd);
    GotoDlgCtrl(pWnd);
    return TRUE;
 }

Q SHBrowseForFolder问题:windows2000下当用户选择桌面上的文件夹"a 在 bSvr 上"后,函数返回'C:/Documents and Settings/Administrator/
T
由于'a 在 bSvr 上'是指向局域网服务器上某文件夹的快捷方式,所以向'该文件夹'(其实是快捷方式)下写文件时会出错。

但是在弹出选择文件夹对话框时,如选择‘a 在 bSvr 上’的‘NewFolder‘夹时,函数会正确返回:‘//bScr/a/NewFolder’.

如何让那个显示文件夹的对话框不显示快捷方式?或者如何在选择快捷方式后我的程序可以知道?

一下是源代码:

Private Type BROWSEINFO
    hOwner As Long
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As Long
    lParam As Long
    iImage As Long
End Type

Const BIF_RETURNONLYFSDIRS = &H1

Private Declare Function SHGetPathFromIDList _
    Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
    (ByVal pidl As Long, ByVal pszPath As String) As Long
   
Private Declare Function SHBrowseForFolder Lib "shell32.dll" _
    Alias "SHBrowseForFolderA" _
    (lpBrowseInfo As BROWSEINFO) As Long

Public Function BrowseFolder(vCaption As String, Optional vOwnerHwnd As Long = 0) As String
    Dim bi As BROWSEINFO
    Dim r As Long
    Dim pidl As Long
    Dim path As String
    Dim Pos As Integer

If vOwnerHwnd <> 0 Then bi.hOwner = vOwnerHwnd
    bi.pidlRoot = 0&
    bi.lpszTitle = vCaption
    bi.ulFlags = BIF_RETURNONLYFSDIRS
    pidl = SHBrowseForFolder(bi)
    path = Space$(512)
    r = SHGetPathFromIDList(ByVal pidl&, ByVal path)
   
    If r Then
        Pos = InStr(path, Chr$(0))
        BrowseFolder = Left(path, Pos - 1)
    Else
        BrowseFolder = ""
    End If
End Function

A
http://www.csdn.net/develop/read_article.asp?id=22243

打开文件或者目录
为了使用方便,双击列表项时可以在同一窗口打开子目录,或者调用系统的默认处理程序打开文件。如果文件是快捷方式,那么打开快捷方式的目标。

void CPicViewView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLISTVIEW lpnm=(LPNMLISTVIEW)pNMHDR;
    if(lpnm->iItem==-1)return;
    *pResult = 0;
    HRESULT hr=S_OK;
    LPCITEMIDLIST pidlItem=m_arpFolderItems[lpnm->iItem];
    LPITEMIDLIST pidlItemFull=ILCombine(m_pidlFolder,pidlItem);
    LPITEMIDLIST pidlItemTarget=NULL;
    hr=theApp.SHGetTargetFolderIDList(pidlItemFull,&pidlItemTarget);
……
SHGetTargetFolderIDList
这个函数可以获得快捷方式的目标
VC的代码,将就看吧

Q 使用图标的问题,高手请进。
T
我用SHGetFileInfo得到文件图标,但在程序关闭以后,所有用到文件小图标的地方都什么也不显示了,包括资源管理器等,请各位大侠指点。以下是程序。
 hImageList=(HIMAGELIST)SHGetFileInfo("C://",0,&shFi,sizeof(shFi),SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
 if(!hImageList)
  return ;
 .m_hImageList=hImageList;

程序关闭时 if(m_ImageList.m_hImageList)
  m_ImageList.Detach();

A
//set the large and small icon image lists
himlSmall = (HIMAGELIST)SHGetFileInfo( TEXT("C://"),
                                       0,
                                       &sfi,
                                       sizeof(SHFILEINFO),
                                       SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

himlLarge = (HIMAGELIST)SHGetFileInfo( TEXT("C://"),
                                       0,
                                       &sfi,
                                       sizeof(SHFILEINFO),
                                       SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
存HIMAGELIST就可以了,不用CImageList
Assigns an image list to a list view control. You can use this macro or send the LVM_SETIMAGELIST message explicitly.
HIMAGELIST ListView_SetImageList(
    HWND hwnd,
    HIMAGELIST himl,
    int iImageList
);

Q 为什么会出问题?编译是没有错误!!!
T
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
 {
  TRACE0("Failed to create toolbar/n");
  return -1;      // fail to create
 }

if (!m_WzdDialogBar.Create(this,IDD_WZD_DIALOG,CBRS_TOP,
  !m_WzdDialogBar.InitDialog()))//问题就出在这里!!!,一个断定错误!
 {
  TRACE0("Failed to Create Dialog Bar!");
  return -1;
 }

class CWzdDialogBar : public CDialogBar
{
// Construction
public:
 CWzdDialogBar(CWnd* pParent = NULL);   // standard constructor
 BOOL InitDialog();

// Dialog Data
 //{{AFX_DATA(CWzdDialogBar)
 enum { IDD = IDD_WZD_DIALOG };
  // NOTE: the ClassWizard will add data members here
 //}}AFX_DATA

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CWzdDialogBar)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
 //{{AFX_MSG(CWzdDialogBar)
 afx_msg void OnButton1();
 afx_msg void OnButton3();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WZDDIALOGBAR_H__96035782_9BCD_11D5_AC0B_5254AB11DB8B__INCLUDED_)

A
为什么要这么干??如果要用DDX的话,参见
HOWTO: How to Initialize Child Controls in a Derived CDialogBar
ID: Q185672

--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), used with:
Microsoft Visual C++, 32-bit Editions, versions 5.0, 6.0

--------------------------------------------------------------------------------

SUMMARY
When creating a simple CDialogBar, such as one with only CButtons similar to MFC's print preview, it is not necessary to derive from CDialogBar because the parent of CControlBar receives the notification messages from any child controls.

However, in the case of a more complex CDialogBar, which might have a drop- down combo box, a treeview, or ActiveX control, it might be useful to derive from CDialogBar to provide initialization for the child controls.

Because ClassWizard does not support deriving a class from CDialogBar, this article shows the steps necessary to create a class from CDialog and then "convert" the class to CDialogBar.

MORE INFORMATION
To start out, create a CDialog class with the child controls you want to use. You can transform the CDialog class into a CDialogBar class using the following nine steps:

Change the base class from CDialog to CDialogBar in the class declaration. Don't forget to also change the base class in BEGIN_MESSAGE_MAP in the .cpp file.

Change the constructor in both the .h and the .cpp files. Also make the change to the DoDataExchange(). Below are three items to change.

Change the following from

CMyDlgBar (CWnd* pParent = NULL);   // standard constructor

CMyDlgBar:: CMyDlgBar (CWnd* pParent /*=NULL*/)
         : CDialog(CMyDlgBar::IDD, pParent)
      {
         ...

void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
      {
         CDialog::DoDataExchange(pDX);
         ...
to the following:

CMyDlgBar ();   // standard constructor

CMyDlgBar:: CMyDlgBar ()
      {
         ...

void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
      {
         CDialogBar::DoDataExchange(pDX);
         ...
The key to the transformation is the conversion of the virtual OnInitDialog() member function to the WM_INITDIALOG message mapped method by changing the OnInitDialog method and by adding the ON_MESSAGE() handler. You may not have an override of OnInitDialog(). If not, add one before proceeding.
Remove "virtual BOOL OnInitDialog();" from the class header and add "afx_msg LONG OnInitDialog ( UINT, LONG );" in its place. For example:

class CMyDlgBar : public CDialogBar
      {
         ...
      // Implementation
      protected:

// Generated message map functions
         //{{AFX_MSG(CMyDlgBar)
         virtual BOOL OnInitDialog();                // <-Remove this line.
         //}}AFX_MSG

afx_msg LONG OnInitDialog ( UINT, LONG );   // <-Add this line.
         DECLARE_MESSAGE_MAP()
      };
Now, in the class implementation section, make the corresponding changes.

Add "ON_MESSAGE(WM_INITDIALOG, OnInitDialog );" to the message map in the .CPP implementation file. For example:

BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)

//{{AFX_MSG_MAP(CMyDlgBar)
         ...
         //}}AFX_MSG_MAP
         ON_MESSAGE(WM_INITDIALOG, OnInitDialog )    // <-- Add this line.
      END_MESSAGE_MAP()
Now, convert the virtual OnInitDialog() to the message-mapped OnInitDialog().

Make the OnInitDialog() conversion as follows:

Change the following:

BOOL CMyDlgBar::OnInitDialog()
      {
         CDialog::OnInitDialog();   // <-- Replace this line:
            ...
to the following:

LONG CMyDlgBar::OnInitDialog ( UINT wParam, LONG lParam)
      {
                       // <-- with these lines. -->

if ( !HandleInitDialog(wParam, lParam) || !UpdateData(FALSE))
         {
            TRACE0("Warning: UpdateData failed during dialog init./n");
            return FALSE;
         }
         ...
The CDialogBar class doesn't have a virtual OnInitDialog(), and therefore calling one does not work. UpdateData is called to subclass or initialize any child controls.

Make sure the dialog box resource styles to the following:
Style: Child
Boarder: None
Visible: Unchecked
At this point, everything has been reconnected to make the transformation from a CDialog class to a CDialogBar class work correctly. Now, create and use it.

Add an instance of the derived CDialogBar to the CframeWnd-derived class (normally called CMainFrame). For example:

class CMainFrame : public CFrameWnd
      {
          ...
          CMyDlgBar m_myDlgBar;
          ...
      };
Call the create method for the m_myDlgBar variable in the CFrameWnd::OnCreate() method similar to the following:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
      {
         ...
         if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT,
            IDD_DLGBAR1))
         {
            TRACE0("Failed to create dialog bar/n");
            return -1;      // fail to create
         }
         ...
      }
Finally, if you want to support dynamic docking and resizing of the CDialogBar, add the following lines to the end of CMainFrame::OnCreate():

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
      {
         ...
         m_myDlgBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
            CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
         m_myDlgBar.EnableDocking(CBRS_ALIGN_ANY);
         DockControlBar(&m_myDlgBar);

return 0;
      }

REFERENCES
For additional information, please see the following article in the Microsoft Knowledge Base:

Q99161 HOWTO: Derive From Classes not Listed in ClassWizard

Additional query words:

Keywords : kbwizard kbMFC KbUIDesign kbVC500 kbVC600 kbGrpMFCATL kbMFCCtrlBar
Version : winnt:5.0,6.0
Platform : winnt
Issue type : kbhowto
Technology : kbvc

Last Reviewed: March 8, 2000
&copy; 2000 Microsoft Corporation. All rights reserved. Terms of Use.

--------------------------------------------------------------------------------
Send feedback to MSDN.Look here for MSDN Online resources.

Q 请问大虾:如何使自己的透明程序总在最前,但不影响用户对下面的其他程序操作
T 请问大虾:如何使自己的半透明程序窗口总在最前,但不影响用户对下面的其他程序操作?
A 处理一下WM_NCHITTEST(参见CWnd::OnNcHitTest),返回HT_TRANSPARENT

你的程序生成一个OVERLAY(看DirectDraw),这样你的程序就在最高层(高于鼠标)。
看看这个软件吧:http://www.kuihua.net/download/fdj.htm

Q 如何实现像98那样的文件搜索列表? 
T 点一下列表的表头就可以以升序或者降序进行排列的功能是如何实现的?
A
对于虚列表,排序的工作比较简单,更改内部数据的排序方式之后刷新就可以
下面是交换列表项的处理(很旧的代码了,写的繁琐了一点)
BOOL CEnhancedListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
 *pResult = 0;
 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
 // TODO: Add your control notification handler code here
 if(!GetSortable())return FALSE;
 if(m_iSortCol==pNMListView->iSubItem){//click repeatly
  m_bSortAsc=!m_bSortAsc;
 }
 else{
  m_bSortAsc2=m_bSortAsc;
  m_bSortAsc=TRUE;
  m_iSortCol2=m_iSortCol;
  m_iSortCol=pNMListView->iSubItem;
 }
 Sort(m_iSortCol,m_bSortAsc,m_iSortCol2,m_bSortAsc2,TRUE);
 return FALSE;
}
BOOL CEnhancedListCtrl::Sort(int iCol,BOOL bSortAsc,int iCol2/*=-1*/,BOOL
bSortAsc2/*=TRUE*/,BOOL bRedraw/*=FALSE*/)
{
 if(!(GetStyle()&LVS_OWNERDATA))
  return g_listSortByName(*this,iCol,bSortAsc,iCol2,bSortAsc2,bRedraw);
 else
  return FALSE;
}
BOOL g_listSortByName(CListCtrl& list,int iSortCol,BOOL bSortAsc,int
iSortCol2/*=-1*/,BOOL bSortAsc2/*=TRUE*/,BOOL bRedraw/*=FALSE*/)
{
 if(iSortCol==-1)return FALSE;
 if(bRedraw)
  list.SetRedraw(FALSE);
 BOOL bRet;
 CWaitCursor WaitCursor;
 DWORD dwSortOption=0;
 if(bSortAsc)
  dwSortOption|=LVSF_ASCENDING ;
 if(bSortAsc2)
  dwSortOption|=LVSF_ASCENDING2;
 if(iSortCol2!=-1)
  dwSortOption|=LVSF_SECONDARY;
 //save item data
 LPTEMPDATA ptempData;
 for(int i=0;i<list.GetItemCount ();i++){
  ptempData=new TEMPDATA;
  ptempData->strPrimary =list.GetItemText (i,iSortCol);
  if(iSortCol2!=-1)
   ptempData->strSecondary =list.GetItemText (i,iSortCol2);
  ptempData->data =list.GetItemData (i);
  list.SetItemData (i,(LPARAM)ptempData );
 }
 //set sort options
 bRet=list.SortItems((PFNLVCOMPARE)g_listItemCompareByName,dwSortOption);
 //Restore item data
 for(i=0;i<list.GetItemCount ();i++){
  ptempData=(LPTEMPDATA)list.GetItemData (i);
  list.SetItemData (i,ptempData->data );
  delete ptempData;
 }
 if(int iItem=list.GetNextItem(-1,LVNI_FOCUSED)!=-1)
  list.EnsureVisible(iItem,FALSE);
 if(bRedraw)
  list.SetRedraw(TRUE);
 return bRet;
}
//Used by Sorting of ListView;
//Note:this operation will overite the data of items temporary.
int CALLBACK g_listItemCompareByName(LPARAM lParam1, LPARAM lParam2,
 LPARAM dwSortOption)
{
 int nRet;
 BOOL bSecondary=dwSortOption&LVSF_SECONDARY ;
 BOOL bSortAsc=dwSortOption&LVSF_ASCENDING ;
 BOOL bSortAsc2=dwSortOption&LVSF_ASCENDING2;
 CString str1=((LPTEMPDATA)lParam1)->strPrimary ;
 CString str2=((LPTEMPDATA)lParam2)->strPrimary ;
 nRet=str1.Compare (str2);
 if(nRet){
  if(!bSortAsc)//
   nRet=-nRet;
 }
 else{
  if(bSecondary){// primary is the same string
   str1=((LPTEMPDATA)lParam1)->strSecondary ;
   str2=((LPTEMPDATA)lParam2)->strSecondary;
   nRet=str1.Compare (str2);
   if(!bSortAsc2)//
    nRet=-nRet;
  }
 }
 return nRet;
}

--
Command what is yours
Conquer what is not
http://www.csdn.net/develop/author/netauthor/jiangsheng/
http://blog.joycode.com/jiangsheng/
http://jiangsheng.blogone.net
"richardliu" <anonymous@discussions.microsoft.com> 写入邮件
news:086501c3cfab$075b7f60$a501280a@phx.gbl...
> 本人现在写一个关于CListCtrlView的程序,要求在Report显示方式
> 下当用户单示列头时,程序能够对已插入的数据进行自动排序。本
> 人依稀记得要用于ColumnClick、GetDispInfo消息以及相关的回调
> 函数,但记不完整了,请各位能帮小弟一把。谢谢

这是演示代码,不是完整的工程

//if this bit set, sort ascending, otherwise sort descending,
#define LVSF_ASCENDING 0x01;
#define LVSF_ASCENDING2 0x02;
//if this bit set, the secondary sorting enabled, otherwise parameter
//ncolSecondary is ignored. calculated by ncolPrimary and ncolSecondary
#define LVSF_SECONDARY 0x04;
struct DECLARE_DLL_PUBLIC_CLASS TEMPDATA {
 CString strPrimary;
 CString strSecondary;
 DWORD data;
}  ;
typedef TEMPDATA * LPTEMPDATA;

Q 关于alt+f4
T
要屏蔽alt+f4
我的想法是在onkeydown里面判断vk_alt和vk_f4同时按下,然后返回失败
不知道对不对,那么怎样判断是否两个键同时按下
A
HOWTO: Disable the Window Close Button in an MDI Application
ID: Q201553

--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), included with:
Microsoft Visual C++, 32-bit Editions, version 6.0

--------------------------------------------------------------------------------

SUMMARY
This article describes how to disable the close button in the title bar of the main frame and child frame windows of an MFC Multiple Document Interface (MDI) application.

MORE INFORMATION
In some circumstances you may want to prevent the user from clicking the close button in the window's title bar to close a frame window in an MFC application. The close button can be removed by removing the WS_SYSMENU style from the frame window. However, the minimize, maximize, and restore buttons are also removed and cannot be added. This is in accordance to the design of Windows.

To workaround this limitation, you can simulate the functionality of a window without a close button by disabling the close button. In the WM_CREATE message handler for the MDI child frame window (CMDIChildWnd-derived class) disable the close button with the following code:

CMenu *pSysMenu = GetSystemMenu(FALSE);
ASSERT(pSysMenu != NULL);
VERIFY(pSysMenu->RemoveMenu(SC_CLOSE, MF_BYCOMMAND));

When the child frame window is not maximized, the above code prevents the user from closing the child frame window by clicking the close button. When the child frame window is maximized, the above code makes the close button appear disabled. However, a user can still close the child frame window by clicking this window's close button. You can prevent this by trapping the SC_CLOSE command when it is sent to the child frame window and preventing further processing of this command. To do so, use the WM_SYSCOMMAND message handler for the child frame's class, as in the following example:

// CChildFrame is a CMDIChildWnd-derived class.
void CChildFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
    if(nID == SC_CLOSE)
        return;
    CMDIChildWnd::OnSysCommand(nID, lParam);
}

(c) Microsoft Corporation 1999, All Rights Reserved. Contributions by Isaac L. Varon, Microsoft Corporation.

Additional query words: ChildFrame MainFrame

Keywords : kbMDI kbMenu kbMFC KbUIDesign kbVC600 kbGrpMFCATL
Version : winnt:6.0
Platform : winnt
Issue type : kbhowto
Technology : kbvc

Last Reviewed: March 9, 2000
&copy; 2000 Microsoft Corporation. All rights reserved. Terms of Use.

Q I want to replace the cursor with my cwnd object,can you help me?!
T  
A
INFO: Changing the Mouse Cursor for a Window
ID: Q31747
3.00 3.10 WINDOWS kbprg

--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Windows Software Development Kit (SDK) 3.1

--------------------------------------------------------------------------------

SUMMARY
There are two different methods that an application can use to change the mouse cursor in a window:

The application can use the SetCursor function, which will change the mouse cursor immediately.

The application can use the SetClassWord function to change the mouse cursor for all windows of a particular window class. This method affects the mouse cursor only while it resides within the client area of a window of that class.

This article provides additional details regarding these two methods.

MORE INFORMATION
A number of factors should be considered during the design of an application that changes the mouse cursor. The major consideration is that Windows sends the WM_SETCURSOR message any time the mouse cursor moves on the screen. Normally, Windows sends the message to the window "under" the mouse cursor. However, if a window sets the mouse capture, using the SetCapture function, that window receives all mouse messages, without regard to the position of the mouse cursor.

When an application calls SetCursor, the mouse cursor changes to reflect the cursor specified in the call. The cursor retains that shape until SetCursor is called again, either explicitly by the application, by the DefWindowProc function, or by another application.

Because Windows is a nonpreemptive multitasking environment, no other application will gain control of the processor until the application that has the processor releases it. If the application calls one of a number of Windows functions, it can potentially lose control of the processor. For a list of Windows functions that can cause control of the processor to pass between applications, search on the following words in the Microsoft Knowledge Base:

prod(winsdk) and nonpreemptive and multitasking

When the DefWindowProc or DefDlgProc function processes a WM_SETCURSOR message, it calls SetCursor to change the cursor to the default cursor for the application's window.

The application can prevent the cursor from changing by processing the WM_SETCURSOR message. A typical application that processes WM_SETCURSOR will have a global variable for the handle to the current cursor. When the application receives a WM_SETCURSOR message, it checks the global variable. If the variable is NULL, the application passes the WM_SETCURSOR message to DefWindowProc. Otherwise, the application calls SetCursor with the value in the global variable. To return the cursor to the window default cursor, set the global variable to NULL.

When Windows sends a WM_SETCURSOR message, it places the hit-test area code into the low-order word of the lParam parameter. The application can use the hit-test area code to determine what particular portion of the window is "under" the mouse cursor. For more information on the hit-test area codes, see the documentation for the WM_NCHITTEST message in the "Microsoft Windows Software Development Kit Reference Volume 1."

Additional query words: 3.00 3.10 RegisterClass

Keywords : kb16bitonly kbInput kbMouse kbSDKPlatform kbWndw
Version : WINDOWS:3.1
Platform : WINDOWS
Issue type : kbinfo
Technology :

When the DefWindowProc or DefDlgProc function processes a WM_SETCURSOR message, it calls SetCursor to change the cursor to the default cursor for the application's window.

Q 怎样在弹出式菜单中使用CheckMenuItem?我用LoadMenu(),GetSubMenu(),然后在菜单项响应处理中使用CheckMenuItem,再弹出菜单一看却无变化.(问题很菜,见笑)
T 怎样在弹出式菜单中使用CheckMenuItem?我用LoadMenu(),GetSubMenu(),然后在菜单项响应处理中使用CheckMenuItem,再弹出菜单一看却无变化.(问题很菜,见笑)
A
我已经是第N次回答这种问题了……
下次提问前搜索一下论坛先
对话框是没有空闲时间处理的。需要加一些模拟的框架的代码才行。
http://www.csdn.net/expert/Topic/295/295161.shtm
Q 看在我已经熬了两个晚上的份上,各位帮帮忙,我的眼睛已经熬红了--一个向MDI程序插入MENU的问题 
T
我做一个浏览器程序现在要向主菜单中插入[收藏]菜单,在CMainFrame的OnCreate函数中有如下代码,这是个MDI
.....
CMenu *pMenu,*tMenu;               //(1)
tMenu=GetMenu();                   //(2)
pMenu=tMenu->GetSubMenu(3);        //(3)
.....
当执行到第二步时,可以获得主菜单的指针(不确定是否是真正的指针).然而在执行到第三步时,系统报错.经调试发现,在第三步执行时,tMenu变成了000000,也就是NULL,始终弄不懂已经保存下来的变量怎么会变NULL.因为这个原因,程序始终不能通过这里.
在跟踪调试到系统中时,发现程序产生一个CTEMPMENU,我在SDI的ONCREATE中同样的代码可以正确地执行,但同样的代码在MDI的同样位置就是不行.不知道是什么问题
我是打算在MDI中插入[收藏]菜单.
         谢谢!
A
1在CChildFrame的WM_INITMENUPOPUP里面把菜单改掉
2重载CDocument::GetDefaultMenu
3在文档模板创建的时候修改菜单
修改方法参见MFCIE示例

上述方法只需采用其中一种

ChildFrame是没有Menu的,在激活ChildFrame的时候会用当前CMDIChildWnd::m_hMenuShared替换主菜单。但是直接修改CMDIChildWnd::m_hMenuShared会有问题,建议重载
CDocument::GetDefaultMenu

1更正为
在CMainFrame的WM_INITMENUPOPUP里面把菜单改掉

MDI的CMainFrame没有视图的,ChildFrame才有。

Q 请问导航图如何实现?(玩过红警的更容易解答)
T
我时作组态软件的,我的把组态图画布定义的很大,想通过做一个导航框来实现方便
图像管理和移动(就象红警中的缩略地图一样,即可看全貌也可通过用鼠标拖动当前显示框来看图像的其它部分),请大家给我出个主意这玩艺该如何实现,请大家踊跃讨论!
A
void CEMapView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
 // TODO: Add your specialized code here and/or call the base class
 CScrollView::OnPrepareDC(pDC, pInfo);
 CEMapDoc* pDoc = GetDocument();
 CSize sizeDoc = pDoc->GetSize();
 CPoint ptOrg;
 CRect rectClient;
 GetClientRect(&rectClient);
 pDC->DPtoLP(&rectClient);
 ptOrg.x = min(-sizeDoc.cx / 2,-rectClient.Size().cx/2);
 ptOrg.y = max(sizeDoc.cy / 2,-rectClient.Size().cy/2);
 // ptOrg is in logical coordinates
 pDC->SetWindowOrg(ptOrg);
}
void CEMapThumbnailView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
 // TODO: Add your specialized code here and/or call the base class
 CEMapDoc* pDoc = GetDocument();
 CSize sizeDoc=pDoc->GetSize();
 CRect rectClient;
 GetClientRect(&rectClient);
 pDoc->PixelToLongEngish(&rectClient);
 CView::OnPrepareDC(pDC, pInfo);
 pDC->SetMapMode(MM_ANISOTROPIC);
 CSize sizeView;
 LONGLONG x1y2,x2y1;
 x1y2=Int32x32To64(sizeDoc.cx,rectClient.Width());
 x2y1=Int32x32To64(sizeDoc.cy,rectClient.Height());
 if(x1y2>x2y1){//image is too wide,stretch y
  sizeView.cx=::MulDiv(sizeDoc.cy,rectClient.Width(),rectClient.Height());
  sizeView.cy=sizeDoc.cy;
 }
 else{//image is too thin,stretch x
  sizeView.cx=sizeDoc.cx;
  sizeView.cy=::MulDiv(sizeDoc.cx,rectClient.Height(),rectClient.Width());
 }
 GetClientRect(&rectClient);
 pDC->SetWindowExt(sizeView);
 pDC->SetViewportExt(rectClient.Width(),-rectClient.Height());
 CPoint ptOrg;
 ptOrg.x = -sizeView.cx/2;
 ptOrg.y = sizeView.cy/2;
 // ptOrg is in logical coordinates
 pDC->SetWindowOrg(ptOrg.x,ptOrg.y);

}
void CEMapThumbnailView::OnDraw(CDC* pDC)
{
 CEMapDoc* pDoc = GetDocument();
 // TODO: add draw code here
 CRect rectMap=pDoc->GetMapRect() ;
 pDoc->m_dibMapCurrent.Draw(*pDC,&rectMap);
 if(pDoc->m_pEMapView->GetSafeHwnd()){
  CRect rectViewPort;
  pDoc->m_pEMapView->GetViewPort(&rectViewPort);
  CSize sizeTotal=pDoc->m_pEMapView->GetTotalSize();
  //rectViewPort.OffsetRect(sizeTotal.cx/2,sizeTotal.cy/2);
  m_RectTracker.m_rect.left=MulDiv(rectViewPort.left,rectMap.Width(),sizeTotal.cx);
  m_RectTracker.m_rect.right=MulDiv(rectViewPort.right,rectMap.Width(),sizeTotal.cx);
  m_RectTracker.m_rect.top=-MulDiv(rectViewPort.bottom,rectMap.Height(),sizeTotal.cy);
  m_RectTracker.m_rect.bottom=-MulDiv(rectViewPort.top,rectMap.Height(),sizeTotal.cy);
  pDC->LPtoDP(m_RectTracker.m_rect);
  m_RectTracker.Draw(pDC);
 }
}
void CEMapView::GetViewPort(LPRECT lpRect)
{
 GetClientRect(lpRect);
 ClientToDoc(lpRect);
}

Q 调用ProcessShellCommand()时, 出现"Failed to create empty document."错误.
T
Win98,VC++6.0,单文档界面,InitInstance()中调用ProcessShellCommand()时, 出现"Failed to create empty document."错误.有一台机器上出现这种错误,其他大多数机器上又没有这种错误.
烦闷啊!
可能是什么原因呢?
A check the return code of CYourDocument::OnNewDocument()

上次记错了,OnNew是在后面
CDocTemplate::CreateNewDocument和CDocTemplate::CreateNewFrame失败的话都会导致这个提示。在程序没有错误的情况下,除非内存不足,否则CDocTemplate::CreateNewDocument不太可能失败。CDocTemplate::CreateNewDocument new了一个Document,然后添加到CDocTemplate的文档列表里面)

CDocTemplate::CreateNewFrame new了一个FrameWnd,调用了CFrameWnd::LoadFrame,而CFrameWnd::LoadFrame是可能失败的。FrameWnd在处理WM_CREATE的过程中失败就可能导致这种情况。通常的原因是CFrameWnd::CreateView失败。

注册组件的时候,要注意组件的ProgID。为了安全起见,需要先撤销原有控件的注册,才能正常注册组件。

Q 怎么编程去点击别的程序的按钮???
T
我知道可以用SendMessage()
可是,句柄呢?
ID?
怎么控制那个按钮阿?
A
//this program use EnumChildWindows to enumerate all the child windows of the dialog... can be changed to enumerate all the child windows of the desktop.

#include <afxtempl.h>

// Information about child controls in the Visual Basic
      // ActiveX control.
      typedef struct xcontrol_info
      {
         HWND hwnd;            // handle of child control
         char mnemonic_char;   // mnemonic character key for the control
      }
      XCONTROL_INFO;

class CTestVBDlg : public CDialog
      {
      ...
         // Array of info for child controls.
         CArray<XCONTROL_INFO, XCONTROL_INFO> m_XControlInfo;
      ...
      }

// Callback function for EnumChildWindows() API
      BOOL CALLBACK EnumActiveXControlChildProc(HWND hwnd, LPARAM lParam)
      {
         CArray<XCONTROL_INFO, XCONTROL_INFO>* arr =
         (CArray<XCONTROL_INFO, XCONTROL_INFO>*)lParam;

CString str;
         CWnd*   control = CWnd::FromHandle(hwnd);
         control->GetWindowText(str);
         int index = str.Find('&');   // look for mnemonic
                                      // character keycode
         if (index > -1)
            {
               XCONTROL_INFO info;
               info.hwnd = hwnd;
               info.mnemonic_char = str[index+1];
               arr->Add(info);
            }

return TRUE;
      }

BOOL CTestVBDlg ::OnInitDialog()
      {
         CDialog::OnInitDialog();
         ...

// Setup a callback function for EnumChildWindows() API to
         // enumerate all child windows of the ActiveX control.
         HWND hcontrol = GetDlgItem(IDC_VB_CONTROL1)->GetSafeHwnd();
         EnumChildWindows(hcontrol, EnumActiveXControlChildProc,
            (LPARAM) &m_XControlInfo);
         return TRUE;
      }
      void CTestVBDlg ::OnSysCommand(UINT nID, LPARAM lParam)
      {
         if ((nID & 0xFFF0) == IDM_ABOUTBOX)
         {
               CAboutDlg dlgAbout;
               dlgAbout.DoModal();
         }
         else
         {
            // If user pressed an accelerator keystroke, loop through the
            // array to find out if it is one of the access keys for a
            // child control in the Visual Basic ActiveX control.
            BOOL  trap_accel = nID == SC_KEYMENU;
            if (trap_accel)
            {
               int size =    m_XControlInfo.GetSize();
               for (int i = 0; i < size; i++)
               {
                  if (toupper(LOWORD(lParam)) ==
                     toupper(m_XControlInfo[i].mnemonic_char))
                  {
                     HWND child = m_XControlInfo[i].hwnd;
                     ::SetFocus(child);

::SendMessage(child, BM_CLICK, 0, 0L);  // OPTIONAL!!!
                  }
               }
            }

if (!trap_accel)
         CDialog::OnSysCommand(nID, lParam);
         }
      }

Q 大家都知道弹出模式对话框(CDialog), 有谁知道如何产生 弹出模式CFrameWnd(他是个CFrameWnd, 不过弹出后, 会锁定母CFrameWnd) 多多UP
T 大家都知道弹出模式对话框(CDialog), 有谁知道如何产生 弹出模式CFrameWnd(他是个CFrameWnd, 不过弹出后, 会锁定母CFrameWnd)
A
CReportErrorDlg::OnSend()
{
  CWhatWereYouDoingDlg dlg1(this);
  dlg1.m_strString = m_strWhatWereYouDoing;
  if(dlg1.DoModal() == IDOK)
  {
  m_strWhatWereYouDoing = dlg1.m_strString;
    HINSTANCE hMail = NULL;
    hMail = ::LoadLibraryA("MAPI32.DLL");
    if (hMail == NULL)
    {
  AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD);  return;
    }
    ASSERT(hMail != NULL);

ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG,  MapiMessage*, FLAGS, ULONG);
  (FARPROC&)lpfnSendMail = GetProcAddress(hMail,   "MAPISendMail");
    if(lpfnSendMail == NULL)
    {
  AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL);  return;
    }
  ASSERT(lpfnSendMail != NULL);

// make a recipient
  MapiRecipDesc rec;
 
    char szRName[] = "Clever Programmer";
    char szRAddress[] =   "SMTP:sendyourerrorsto@yourcompanynotmine.com";
  memset(&rec, 0, sizeof(rec));
  rec.ulRecipClass = MAPI_TO;
    rec.lpszName = szRName; 
  rec.lpszAddress = szRAddress;
 
    char szSubject[] = "An exception has occurred";
 
    // prepare the message
------------------------
   
    MapiMessage message;
  memset(&message, 0, sizeof(message));
   
  message.nRecipCount = 1;
  message.lpRecips = &rec;
  message.lpszSubject = szSubject;

CString s =m_strWhatWereYouDoing;
    s +="/n";
  PrepareErrorMessage(s);

message.lpszNoteText =   s.GetBuffer(s.GetLength());

// prepare for modal dialog box
  AfxGetApp()->EnableModeless(FALSE);
    HWND hWndTop;
    CWnd* pParentWnd= CWnd::GetSafeOwner(NULL,   &hWndTop);

// some extra precautions are required to use
    //MAPISendMail as it tends to enable the parent
    // window in between dialogs (after the login
    // dialog, but before the send not dialog).
  pParentWnd->SetCapture();
  ::SetFocus(NULL);
  pParentWnd->m_nFlags |= WF_STAYDISABLED;

int nError =lpfnSendMail(0,   (ULONG)pParentWnd->GetSafeHwnd(),
  &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
  s.ReleaseBuffer();

// after returning from the MAPISendMail call,
    // the window must be re-enabled and focus
    // returned to the frame to undo the workaround
    // done before the MAPI call.
     ::ReleaseCapture();
  pParentWnd->m_nFlags &= ~WF_STAYDISABLED;

pParentWnd->EnableWindow(TRUE);
  ::SetActiveWindow(NULL);
  pParentWnd->SetActiveWindow();
  pParentWnd->SetFocus();
    if (hWndTop != NULL)
      ::EnableWindow(hWndTop, TRUE);
  AfxGetApp()->EnableModeless(TRUE);

if (nError != SUCCESS_SUCCESS &&  nError !=MAPI_USER_ABORT &&  nError !=MAPI_E_LOGIN_FAILURE)
    {
  AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND);
    }
    ::FreeLibrary(hMail);
  }
}

注意这些
开始模态
// prepare for modal dialog box
  AfxGetApp()->EnableModeless(FALSE);
    HWND hWndTop;
    CWnd* pParentWnd= CWnd::GetSafeOwner(NULL,   &hWndTop);

// some extra precautions are required to use
    //MAPISendMail as it tends to enable the parent
    // window in between dialogs (after the login
    // dialog, but before the send not dialog).
  pParentWnd->SetCapture();
  ::SetFocus(NULL);
  pParentWnd->m_nFlags |= WF_STAYDISABLED;

结束模态
// after returning from the MAPISendMail call,
    // the window must be re-enabled and focus
    // returned to the frame to undo the workaround
    // done before the MAPI call.
     ::ReleaseCapture();
  pParentWnd->m_nFlags &= ~WF_STAYDISABLED;

pParentWnd->EnableWindow(TRUE);
  ::SetActiveWindow(NULL);
  pParentWnd->SetActiveWindow();
  pParentWnd->SetFocus();
    if (hWndTop != NULL)
      ::EnableWindow(hWndTop, TRUE);
  AfxGetApp()->EnableModeless(TRUE);

界面(1):对话框和菜单 打印和按钮等杂项相关推荐

  1. 字面常量_从字面上看,“打印屏幕”按钮是否可以打印屏幕(并且可以再次打印)吗?

    字面常量 The computing landscape is full of vestigial bits and pieces from the history of computer devel ...

  2. 【转】走进windows编程的世界-----对话框、文本框、按钮

    一.对话框 1 对话框的分类 2 对话框的基本使用方式 3 对话框资源 4 有模式对话框的使用 int DialogBox(  HINSTANCE hInstance,  LPCTSTR lpTemp ...

  3. 猎豹MFC--CMenu菜单 设置主菜单 给主对话框设置菜单 设置快捷菜单

    设置主菜单(不是快捷菜单): 给主对话框设置菜单: 效果如下: 修改菜单的ID使之便于记忆: 给菜单添加消息处理: 添加处理代码: 设置快捷菜单: 打开对话框,属性添加消息  上文菜单  快捷菜单消息 ...

  4. vb6 打印选项对话框_图纸打印次数太多,不知道哪次才是最新的?用打印戳记区分效果好...

    原创:就说我在开发区 使用AutoCAD从事设计工作的朋友们不知道有没遇到过这种情况: 图纸在反复修改打印的过程中,由于图纸内容高度相似,往往搞不清究竟哪个才是最新版本的图纸了. 这种情况下,细致入微 ...

  5. Material Design【Android-Toolbar,滑动菜单,悬浮按钮,卡片布局,下拉刷新和可折叠式标题栏及案例】

    文章目录 Material Design--界面设计 1.Toolbar,标题栏 2.滑动菜单 3.悬浮按钮和可交互提示 4.卡片布局 5.下拉刷新 6.可折叠式标题栏 Material Design ...

  6. 孙鑫对话框二中为什么要对按钮控件新建一个类(小结,5.2给出了结论)

    为类添加消息处理函数与成员变量,因为要对控件添加WM_MOUSEMOVE消息处理函数,而控件变量本身 不能加消息处理函数,只有类才能添加,所以要创建CNewButton类,然后使按钮控件属于这个类,当 ...

  7. android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)

    菜单是应用程序中非常重要的组成部分,能够在不占用界面空间的前提下,为应用程序提供了统一的功能和设置界面,并为程序开发人员提供了易于使用的编程接口 Android系统支持三种菜单 选项菜单(Option ...

  8. 实现带下拉菜单的工具栏按钮

    在工具栏中使用真彩色图标 实现带下拉菜单的工具栏按钮 20050916

  9. 解决微信“聊天界面中的新消息通知”设置按钮不见了问题

    原因 解决微信"聊天界面中的新消息通知"设置按钮不见了问题 解决方法 开启"接收新消息通知"后,"聊天界面中的新消息通知"设置按钮就会出现

最新文章

  1. 程序还没写完只能当然计算器用,先发过来用着后面的慢慢写
  2. 人工智能写散文之错位时空
  3. LSTM入门学习——结合《LSTM模型》文章看
  4. svn(subversion)代码版本管理在linux下的一些常见使用命令
  5. Codeforces 482E ELCA (LCT)
  6. Java8-Guava实战示例
  7. 前端学习(2917):上午回顾
  8. 打击犯罪(信息学奥赛一本通-T1386)
  9. 记录——《C Primer Plus (第五版)》第十一章编程练习第一题
  10. ansible之安装与简单使用
  11. 《『若水新闻』客户端开发教程》——09.代码编写(1)
  12. Python入门--else语句
  13. 1005 地球人口承载力估计
  14. 侧信道攻击之模板攻击
  15. 十分钟掌握Google Guice(上)
  16. 基于智能手机传感器数据的人类行为识别
  17. 烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一 个小时十五分钟呢?(微软面试题)
  18. 计算机登录界面没有用户显示不出来,电脑开机时提示用户界面失败:无法加载登录用户界面的解决方法...
  19. 我涉及的数据可视化的实现技术和工具
  20. 黄梯云主编管理信息系统课后答案1-6

热门文章

  1. 游戏保护_CRC32检测
  2. 如何用计算机记英语词汇,计算机常用英语词汇大全
  3. 车站椅子上密密麻麻的孔,是为了方便放屁吗?
  4. 【大数据框架及实战2】---初识
  5. micro-app 微前端脚手架搭建
  6. Unity秒表计时器
  7. 「Git」常用工作流介绍
  8. KBQA知识总结(学习笔记)
  9. 芯来科技开源软件调试命令解析(nuclei-linux-sdk、openocd.cfg)
  10. 通过JDBC-ODBC连接SQL Server数据库