一个基于对话框的程序,对话框界面上有很多控件,我是在1024*768下面设置的对话框大小,可是当我在800*600下显示时,对话框不能完整显示,由于太大一部分显示不出来,因此我想根据分辨率的大小来动态改变对话框及其上的控件的大小。请问我应该怎么做?

解决方案 »

  1.   

    可以在启动时判断分辨率来设置控件的大小,不过这样比较麻烦。还有一种办法,就是做两个MFC扩展DLL,把对话框资源放在DLL中,一个按1024*768布局,另一个则按800*600布局,可执行文件里不要放资源,然后在启动程序时根据分辨率的不同加载不同DLL就行了。
      

  2.   

    这样可以实现,但很麻烦,我相信你并不想尝试这样痛苦的工作事实上,通常的做法是在800*600下开发,这样到了1024*768下面也不会难看!最好考虑一下你的潜在客户最常用的分辨率(如果有可能知道的话!)但最好还是在800*600下安排你的界面。可以用windows的api函数取得屏幕长和宽(像素),然后以此设定你的form和上面控件的大小,但同时可能还要考虑它们的位置的变化!
      

  3.   

    dll的方法太麻烦了,因为我这个对话框界面是主对话框的界面,用dll不大好吧
      

  4.   

    如果你的程序已经写好了,改成DLL并不麻烦,如果做成以后再修改界面比如增加按钮事件什么的可能就稍麻烦一些了。只要在app的initinstance中加载dll,exitinstance中卸载就行了
      

  5.   

    如果你的控件不多,我觉得还是先判断分辨率,再移动控件方便,因为用dll面太窄,毕竟分辨率可以有很多种。
      

  6.   

    照snailmmx(卧牛)说的方法,只要在app的initinstance中加载dll,那CSmartDlg::CSmartDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CSmartDlg::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CSmartDlg)
    // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    这段代码要怎么变呢
      

  7.   

    不用变,因为基于mfc的程序会自动在其所加载的模块(exe,dll)中搜索资源,你看一下appwizard生成的MFC扩展DLL的源码,在dllmain的最后一句是个new CDynLinkLibrary(EcgResDLL); 这相当于生成一个“模块链”上的节点,只要保证加载的DLL正确,m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);就可以找到资源。普通的win32dll或MFC常规DLL则不行
      

  8.   

    谢谢!我还是不是很明白。
    假设在这个dll的资源中我新建了一个对话框,那在dllmain中要写些什么来跟这个对话框相联系呢
    在我的应用程序的initinstance中哪个地方加载这个dll呢
    BOOL CSmartApp::InitInstance()
    {
    m_pApp = (CSmartApp*) AfxGetApp(); AfxEnableControlContainer(); // Standard initialization
    // If you are not using these features and wish to reduce the size
    //  of your final executable, you should remove from the following
    //  the specific initialization routines you do not need.#ifdef _AFXDLL
    Enable3dControls(); // Call this when using MFC in a shared DLL
    #else
    Enable3dControlsStatic(); // Call this when linking to MFC statically
    #endif CSmartDlg dlg;
    m_pMainWnd = &dlg;
    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with OK
    }
    else if (nResponse == IDCANCEL)
    {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with Cancel
    } // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application's message pump.
    return FALSE;
    }这些部分我要做什么改动和替换呢?能详细一点吗?
    谢谢
      

  9.   

    为app类声明一个成员变量HINSTANCE hResDll;,在initinstance中随便什么地方(比方说开始)加入如下代码
    //获取分辨率
    HDC hDC=::GetDC(NULL);
    long nPixelWidth=GetDeviceCaps(hDC,HORZRES);
    ::ReleaseDC(NULL,hDC);
    //根据不同分辨率加载不同的资源
    if( nPixelWidth<=800 )
    hResDll=::LoadLibrary(_T("Res800.dll"));
    else
    hResDll=::LoadLibrary(_T("Res1024.dll"));
    然后在exitinstance中加入freelibrary(hresdll)就可以了。
    做资源DLL最好是在程序写好以后将资源脚本中的代码从主程序cut/paste到dll的资源脚本中,如果你
    在dll中从头去做一个对话框,然后想在主程序中使用用它的话则会很麻烦,因为这样appwizard提供的辅助功能都不能用了。
      

  10.   

    非常感谢snailmmx(卧牛)!
    “做资源DLL最好是在程序写好以后将资源脚本中的代码从主程序cut/paste到dll的资源脚本中,如果你
    在dll中从头去做一个对话框,然后想在主程序中使用用它的话则会很麻烦,因为这样appwizard提供的辅助功能都不能用了。”
    是什么意思啊?
    其实调用dll我也调用过,我就是不明白为什么调用一次dll,程序的主界面就会改变,可能是dll中的技巧,所以您上面的这段话我不明白,能详细解释一下吗?
      

  11.   

    //获取屏幕的分辨率
     int nFullWidth=GetSystemMetrics(SM_CXSCREEN);//屏幕宽度
    int nFullHeight=GetSystemMetrics(SM_CYSCREEN);//屏幕高度然后,在OnInitDialog中SetWindowPosition,就能改变对话框大小.不过我不知道对应的控件怎么变化.GZ
      

  12.   

    to 52001314(passenger),这个我也知道,但是都这样调整的话,如果控件多了工作量企不是很大?而且还要算算具体的位置,太麻烦了!
      

  13.   

    snailmmx(卧牛),你的意思是不是把主程序的Resource.h和.rc文件中的代码cut到dll工程的Resource.h和.rc文件中去?
      

  14.   

    .rc中与那个对话框相关部分的cut过去,
    而resource.h中对应的资源ID的定义则要copy过去.
    "如果你在dll中从头去做一个对话框,然后想在主程序中使用用它的话则会很麻烦",意思是说你在DLL中新加了一个对话框IDD_DIALOG1,然后在主程序里想使用它,一般来说要生成一个对应该对话框的类,而如果主程序中没有这个对话框的资源,那么就无法用classwizard自动生成对应于IDD_DIALOG1的类了。
    至于加载DLL后界面改变,是因为程序在运行过程中,对话框的事件、行为是放在程序代码(.h,.cpp)中,而外观则是放在资源中,资源一般在.rc中编写,编译为.res后再链接进.exe中,比如about对话框中有这么一行enum { IDD = IDD_ABOUTBOX };,而构造函数又会调用CDialog(CAboutDlg::IDD),也就是根据IDD_ABOUTBOX指定的资源来决定对话框的外观。把资源编译进DLL后,加载的DLL不一样,资源也就不一样了,所以对话框 的外观会改变。
      

  15.   

    snailmmx(卧牛),我照你的方法做了,dll资源中的对话框的确变成了应用程序的对话框,可是我启动应用程序的时候什么都没有显示都退出了啊,在dll的dllmain函数中不需要写任何东东吗?
      

  16.   

    如果在DLL中的对话框里新增一个按钮,就要把DLL的resource.h中对应的资源ID定义拷到主程序的resource.h中去,还要手动为主程序对话框类添加消息处理函数及消息映射(message_map)
      

  17.   

    谢谢snailmmx(卧牛) ,马上给分!