无法重新定位页面(子对话框)以适合选项卡控件的显示区域 [英] Can't reposition page (child dialog box) to fit tab control's display area

查看:72
本文介绍了无法重新定位页面(子对话框)以适合选项卡控件的显示区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将对话框作为单独的页面插入到选项卡控件中。



我已在资源编辑器中成功创建了对话框,其中包含所有必需的样式。



由于我的应用程序使用视觉样式,我遇到了对话框子控件(单选按钮,轨迹栏等)的透明度问题。



我在 EnableThemeDialogTexture API中找到了解决方案。在 WM_INITDIALOG 中调用它可以解决对话框子控件的透明度问题。但是,此API将选项卡控件的背景部分绘制为对话框的背景。



将对话框作为页面插入后,对话框和选项卡背景之间的不匹配将显示在 Windows XP 。请参阅此图片 [ ^ ]。



我在这里问及 Stack Overflow [ ^ ]为什么会这样,并得到答案。



我试图重新定位对话框以适应标签控件的显示区域但是没有成功。我离开了3个像素。



我将提交下面重现我的结果的代码,其背后的逻辑将在评论中。



创建代码的说明重现问题的示例:



1.)创建 Visual Studio中的默认Win32项目;



2.)在资源编辑器中创建一个小对话框,并为每个添加2或3个控件;



我添加了轨迹栏,单选按钮,复选框和静态控件;当需要透明度时,这些都是有问题的;



3.)在 //消息处理程序上面添加以下对话框程序您的 .cpp 模板中的<。code>:



 INT_PTR CALLBACK FirstTabProc(HWND hDlg,UINT消息,WPARAM wParam,LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (消息)
{
case WM_INITDIALOG:
EnableThemeDialogTexture(hDlg,ETDT_ENABLETAB);
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}





4.)将标签控件添加到关于对话框,它在您的资源编辑器中;



5.)将以下 WM_INITDIALOG 处理程序添加到 INT_PTR CALLBACK关于(HWND hDlg,UINT消息,WPARAM wParam,LPARAM lParam)对话框程序,在 .cpp 模板中:

  case  WM_INITDIALOG:
{
HWND hwndTab = GetDlgItem(hDlg,IDC_TAB1 );

RECT rcTab = { 0 }, // 整个选项卡客户区的矩形
rcTabItem = { 0 }; // 标签标题区域的矩形

GetClientRect(hwndTab,& rcTab); // 获取整个客户区

// 获取标签控件的项目区域
// 此矩形的最低值将是rcTab的最高值
TabCtrl_GetItemRect(hwndTab, 0 ,& rcTabItem);

TCITEM tci = { 0 };

tci.mask = TCIF_TEXT | TCIF_PARAM;
tci.pszText = L 第一个标签;

HWND FirstPageDialogBox = CreateDialog(hInst,
MAKEINTRESOURCE(IDD_DIALOG1), // < ---我们创建了IDD_DIALOG1
hDlg,(DLGPROC)FirstTabProc);

ShowWindow(FirstPageDialogBox,SW_SHOW);

// 地图选项卡的矩形到对话框矩形
< span class =code-comment> // 所以我们可以正确调整对话框的大小

POINT pt = { 0 };
ClientToScreen(hwndTab,& pt);
ScreenToClient(hDlg,& pt);

// 此宏获取标签控件的显示区域
TabCtrl_AdjustRect (hwndTab,FALSE,& rcTab);

// 调整大小对话框并将其移至标签页
MoveWindow(FirstPageDialogBox,
rcTab.left + pt.x, // + pt.x --- >解决方法
rcTabItem.bottom + pt.y + 3 // rcTabItem.bottom + py + 3 --->workaround
rcTab.right - rcTab.left,
rcTab。 bottom - rcTabItem.bottom - 3 // rcTabItem。 bottom - 3 --->workaround
TRUE);

// 将对话框句柄存入lParam
// 这样我就可以访问通知消息的对话框
// 当用户切换标签
tci.lParam =(LPARAM)FirstPageDialogBox;

// 添加此页
SendMessage(hwndTab,TCM_INSERTITEM ,(WPARAM) 0 ,(LPARAM)& tci);
}
return (INT_PTR)TRUE;





6.)现在我们留下了技术细节。首先,我们将在 stdafx.h 中添加以下 #include< windows.h>



  #include   <   windowsx.h  >  
#include < CommCtrl.h >
#include < Uxtheme.h >

#pragma comment(lib,comctl32.lib)
#pragma comment(lib,UxTheme.lib)
#pragma co mment(链接器,/ manifestdependency:\type ='win32'\
name = ' Microsoft.Windows.Common-Controls' version = ' 6.0.0.0' \
processorArchitecture = ' *' publicKeyToken = ' 6595b64144ccf1df' \
language = ' *' \





7.)接下来,我们初始化 ATOM MyRegisterClass(HINSTANCE hInstance)中的常用控件:



 INITCOMMONCONTROLSEX iccex = { 0 }; 
iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_TAB_CLASSES | ICC_STANDARD_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(& iccex);

// 下面将填充WNDCLASSEX结构和其余代码...



这就是全部。请记得在 Windows XP上测试应用程序以查看问题。



问题:



如何将对话框插入标签控件的显示区域,以便它们的背景正确对齐?



谢谢。

解决方案

从这个遥远的记忆中,尝试在插入后执行adjustRect和子移动窗口...标签控件改变大小ISTR



BTW,你必须在每次插入后(或在插入一次后)为所有子节点执行adjustRect,movewindow,因为tabControl标题在每次插入后自行调整大小插入

I am trying to insert dialog boxes, as separate pages, into tab control.

I have created the dialog boxes successfully in resource editor, with all necessary styles.

Since my application uses visual styles, I ran into problem with transparency of the dialog's child controls ( radio button, trackbar and similar ).

I have found a solution in EnableThemeDialogTexture API. Calling it in WM_INITDIALOG solves transparency issues of dialog's child controls. However, this API draws portion of tab control's background as dialog's background.

After inserting the dialog box as a page, mismatch between a dialog's and tab's background appear on Windows XP. Please see this image[^].

I have asked here and on Stack Overflow[^] why is this the case and got an answer.

I have tried to reposition the dialog box to fit tab control's display area but had no success. I am off by 3 pixels.

I will submit code that reproduces my results below, and the logic behind it will be in comments.

INSTRUCTIONS FOR CREATING CODE EXAMPLE THAT REPRODUCES THE PROBLEM:

1.) Create default Win32 project in Visual Studio;

2.) Create small dialog box in resource editor and add 2 or 3 controls for each;

I have added trackbar, radio buttons, checkboxes and static controls; These are problematic when transparency is needed;

3.) Add the following dialog procedure above the // Message handler for about box. in your .cpp template:

INT_PTR CALLBACK FirstTabProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG: 
        EnableThemeDialogTexture(hDlg, ETDT_ENABLETAB);
        return (INT_PTR)TRUE;
    }
    return (INT_PTR)FALSE;
}



4.) add a tab control to the About dialog box, it is in your resource editor;

5.) Add the following WM_INITDIALOG handler to INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) dialog procedure, in your .cpp template:

case WM_INITDIALOG:
{
    HWND hwndTab = GetDlgItem(hDlg, IDC_TAB1);

    RECT rcTab = { 0 }, // rectangle of the entire tab's client area
        rcTabItem = { 0 }; // rectangle of the tab header's area

    GetClientRect(hwndTab, &rcTab);  // get entire client area

    // get tab control's item area
    // the bottom value of this rectangle will be the top value of rcTab
    TabCtrl_GetItemRect(hwndTab, 0, &rcTabItem);  

    TCITEM tci = { 0 };

    tci.mask = TCIF_TEXT | TCIF_PARAM;
    tci.pszText = L"First tab";

    HWND FirstPageDialogBox = CreateDialog(hInst, 
        MAKEINTRESOURCE(IDD_DIALOG1),  // <--- we created IDD_DIALOG1  
        hDlg, (DLGPROC)FirstTabProc);

    ShowWindow(FirstPageDialogBox , SW_SHOW);

    // map tab's rectangle to dialog box rectangle
    // so we can properly resize dialog box

    POINT pt = { 0 };
    ClientToScreen(hwndTab, &pt);
    ScreenToClient(hDlg, &pt);

    // this macro obtains tab control's display area
    TabCtrl_AdjustRect(hwndTab, FALSE, &rcTab);

    // resize dialog box and move it into tab page
    MoveWindow(FirstPageDialogBox , 
        rcTab.left + pt.x,  // + pt.x ---> "workaround"  
        rcTabItem.bottom + pt.y + 3, // rcTabItem.bottom + p.y + 3 ---> "workaround"
        rcTab.right - rcTab.left, 
        rcTab.bottom - rcTabItem.bottom - 3, // rcTabItem.bottom - 3 ---> "workaround"
        TRUE);

    // store dialog box handle into lParam
    // this way I have access to the dialog box for notification messages
    // when user switches tabs
    tci.lParam = (LPARAM)FirstPageDialogBox;

    // add this page
    SendMessage(hwndTab, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tci);
}
    return (INT_PTR)TRUE;



6.) Now we are left with technicalities. First we shall add the following in stdafx.h just below #include <windows.h> :

#include <windowsx.h>
#include <CommCtrl.h>
#include <Uxtheme.h>

#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "UxTheme.lib")
#pragma comment( linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
language='*'\"")



7.) Next, we initialize common controls in ATOM MyRegisterClass(HINSTANCE hInstance) :

INITCOMMONCONTROLSEX iccex = { 0 };
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_TAB_CLASSES | ICC_STANDARD_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(&iccex);    

// below will be filled WNDCLASSEX structure and the rest of the code...


That would be all. Please remember to test the application on Windows XP to see the problem.

QUESTION:

How do I insert dialog box into tab control's display area, so their background's properly align?

Thank you.

解决方案

from some distant memory of this, try doing the adjustRect and child movewindow AFTER the insertion ... the tab control changes size ISTR

BTW, you'll have to do an adjustRect, movewindow for all children after each insert (or once after a block insert), because the tabControl header resizes itself after each insertion


这篇关于无法重新定位页面(子对话框)以适合选项卡控件的显示区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆