精华内容
下载资源
问答
  • Qt设置常见窗口背景色几种方式
    2021-10-25 21:10:01

    常见窗口背景色

    总结qt 常见设置QWidget 类型窗口背景色几种方式

    1. setStyleSheet
    ui.widget->setStyleSheet("QWidget{background: black;}");
    
    1. setPalette
    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true));
    
    1. 自定义窗口paintEvent
    void MyWidget::paintEvent(QPainterEvent* event)
    {
    	Q_UNUSED(event);
    	QPainter painter(this);
    	painter.setPen(Qt::NoPen);
    	painter.setBrush(Qt::red);
    	painter.drawRect(rect());
    }
    

    拓展

    如果设置背景透明

    setAttribute(Qt::WA_TranslucentBackground, true);
    
    Note:
    On Windows the widget also needs the Qt::FramelessWindowHint window flag to be set. This flag is set or cleared by the widget's author.
    
    更多相关内容
  • Windows 窗口类型

    千次阅读 2016-06-07 11:32:41
    windows编程中,最基本的就是窗口了,调用函数CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth,int nHeight,HWND hWndParent, HMENU hMenu,...
    windows编程中,最基本的就是窗口了,调用函数CreateWindow ( LPCTSTR lpClassName,  LPCTSTR lpWindowName,  DWORD dwStyle,  int x,  int y,  int nWidth, int nHeight, HWND hWndParent,  HMENU hMenu, HANDLE hlnstance, LPVOID lpParam)

    ,指定参数dwStyle可以创建各式各样的窗口,为了方便,特从MSDN上翻译出dwStyle可取值得各种类型,以供以后编程查阅方便。

    WS_BORDER 带边框的窗口
    WS_CAPTION 带标题栏窗口,包含WS_BORDER 属性
    WS_CHILD 子窗口,带有此风格的窗口没有菜单栏,与WS_POPUP不能共用
    WS_CHILDWINDOW 与WS_CHILD一样
    WS_CLIPCHILDREN 创建父窗口时使用,当父窗口绘画时,子窗口区域无效
    WS_CLIPSIBLINGS 排除子窗口之间的相对区域,也就是,当一个指定的子窗口接收到WM_PAINT消息时,WS_CLIPSIBLINGS 风格 将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。如果未指定WS_CLIPSIBLINGS风格,并且子窗口是层 叠的,则在重绘子窗口的客户区时,就会重绘邻近的子窗口
    WS_DISABLED 指定窗口不接受用户的任何输入信息。创建了具有该属性的窗口口,可以使用 EnableWindow函数来改变这个属
    WS_DLGFRAME 具有边框属性的对话框,没有标题栏
    WS_HSCROLL 具有水平滚动条
    WS_MAXIMIZE 最大化窗口
    WS_ICONIC 最小化窗口,与WS_MINIMIZE 一样
    WS_GROUP 指定一组控制的第一个控制。这个控制组由第一个控制和随后定义的控制组成,自第二个控制开始每个控制,具 有WS_GROUP风格,每个组的第一个控制带有WS_TABSTOP风格,从而使用户可以在组间移动。用户随后可以 使用光标在组内的控制间改变键盘焦点
    WS_MAXIMIZEBOX 具有最大化按钮的窗口,不能与WS_EX_CONTEXTHELP 共用,且WS_SYSMENU必须指定
    WS_MINIMIZE 与WS_ICONIC 一样
    WS_MINIMIZEBOX 具有最小化按钮的窗口,不能与WS_EX_CONTEXTHELP 共用,且WS_SYSMENU必须指定
    WS_OVERLAPPED 层叠窗口,该窗口具有标题栏和边框,与WS_TILED相同
    WS_OVERLAPPEDWINDOW 层叠窗口,与WS_TILEDWINDOW 相同,包含WS_OVERLAPPEDWINDOW=WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
    WS_POPUP 弹出窗口,不能与WS_CHILD 一起使用
    WS_POPUPWINDOW 弹出窗口,WS_CAPTION 与WS_POPUPWINDOW结合一起使用来使菜单栏可见 WS_POPUPWINDOW=WS_POPUP | WS_BORDER | WS_SYSMENU
    WS_SIZEBOX 可调边框的窗口,与WS_THICKFRAME 相同
    WS_THICKFRAME 与WS_SIZEBOX相同
    WS_SYSMENU 创建一个在标题条上带有窗口菜单的窗口,必须同时设定WS_CAPTION风格
    WS_TABSTOP 创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有 WS_TABSTOP风格的控制
    WS_TILED 产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框,和WS_OVERLAPPED 一样
    WS_TILEDWINDOW WS_TILEDWINDOW=WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,层叠窗口,与WS_OVERLAPPEDWINDOW 相同
    WS_VISIBLE 可见窗口, 通过使用ShowWindow 或 SetWindowPos来关闭或开启这个风格
    WS_VSCROLL 带垂直滚动条的窗口

    展开全文
  • android 窗口类型分析

    千次阅读 2017-01-15 20:29:51
    Android窗口类型主要分成了三大类: 1,应用程序窗口。一般应用程序的窗口,比如我们应用程序的Activity的窗口。 2,子窗口。一般在Activity里面的窗口,比如各种菜单等。 3,系统窗口。系统的窗口,比如输入法,...

    1, 概述

    Android窗口类型主要分成了三大类:

    1,应用程序窗口。一般应用程序的窗口,比如我们应用程序的Activity的窗口。

    2,子窗口。一般在Activity里面的窗口,比如各种菜单等。

    3,系统窗口。系统的窗口,比如输入法,Toast,墙纸等。

    WindowManager里面窗口的type类型值定义是一个递增保留的连续增大数值。其实就是窗口的Z-ORDER序列(值越大显示的位置越在上面,需要将屏幕想成三维坐标模式)。

    2 WindowManager/LayoutParams

    2.1 窗口类型

    WindowManager(窗口管理)是如何管理Window呢?

    WindowManager是一个接口,首先看看里面的关键定义,

    窗口类型,

    public int type;

    应用程序窗口

    FIRST_APPLICATION_WINDOW = 1

    第一个应用窗口

    TYPE_APPLICATION = 2

    应用的默认窗口

    LAST_APPLICATION_WINDOW = 99

    最后的应用窗口

    所有acitivty的窗口的值都在[1,99],默认值是TYPE_APPLICATION,WMS在进行窗口叠加时,会动态的改变activity的值。

    子窗口

    子窗口的Z序和坐标空间都依赖于Activity窗口

    所有子窗口的值都在[1000,1999], WMS在进行窗口叠加时,会动态调整子窗口的值。

    系统窗口

    FIRST_SYSTEM_WINDOW     = 2000

    第一个系统窗口

    TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW

    状态条

    TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1

    搜索条

    TYPE_PHONE= FIRST_SYSTEM_WINDOW+2

    来电显示窗口

    TYPE_SYSTEM_ALERT= FIRST_SYSTEM_WINDOW+3

    警告对话框

    TYPE_KEYGUARD= FIRST_SYSTEM_WINDOW+4

    屏保

    TYPE_TOAST= FIRST_SYSTEM_WINDOW+5

    Toast

    TYPE_SYSTEM_OVERLAY= FIRST_SYSTEM_WINDOW+6

     

    TYPE_PRIORITY_PHONE= FIRST_SYSTEM_WINDOW+7

    屏幕保护下的来电显示窗口

    TYPE_SYSTEM_DIALOG= FIRST_SYSTEM_WINDOW+8

     

    TYPE_KEYGUARD_DIALOG= FIRST_SYSTEM_WINDOW+9

    屏幕保护下的对话框窗口

    TYPE_SYSTEM_ERROR= FIRST_SYSTEM_WINDOW+10

    系统错误窗口

    TYPE_INPUT_METHOD= FIRST_SYSTEM_WINDOW+11

    输入法窗口

    系统窗口远不止上面的表格中所展现的,一共定义了33种。

    系统窗口的创建一般不依赖于Activity窗口

    所有系统窗口的值都在[2000,2999], WMS在进行窗口叠加时,会动态调整子窗口的值。有些系统窗口只能出现一个,不能添加多个,否则用户会觉得很乱(体验差)。比如输入法窗口,系统状态条窗口等。

    2.2 窗口内存缓存类型

    public int memoryType; // 保存窗口内存缓存类型

    窗口内存缓存一共有4种,

    public static final int MEMORY_TYPE_NORMAL = 0; //窗口缓冲位于主内存
    public static final int MEMORY_TYPE_HARDWARE=1;//窗口缓冲位于可以被DMA访问,或者硬件加速的内存区域
    public static final int MEMORY_TYPE_GPU = 2; //窗口缓冲位于可被图形加速器访问的区域
    public static final int MEMORY_TYPE_PUSH_BUFFERS = 3; //窗口缓冲不拥有自己的缓冲区,不能被锁定,缓冲区由本地方法提供

    2.3 窗口行为类型

    public int flags; //保存窗口的行为

    窗口行为类型的行为一共32种,数值都是2的n次幂,所以各种flags可以混合使用,直接按位或是最好的方法。

    比如最开始四种行为定义如下,

    //Flag:当该window对用户可见的时候,允许锁屏
            public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001;
            //Flag:让该window后所有的东西都成暗淡
            public static final int FLAG_DIM_BEHIND        = 0x00000002;
            //Flag:让该window后所有东西都模糊(4.0以上已经放弃这种毛玻璃效果)
            public static final int FLAG_BLUR_BEHIND        = 0x00000004;
            //Flag:让window不能获得焦点,这样用户快就不能向该window发送按键事
            public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;
    
    

    2.4 硬件加速类型

    public int privateFlags;  // 保存硬件加速行为

    一共有11种。定义如下,

    public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
    public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
    public static final int PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS = 0x00000004;

    2.5 窗口输入键盘类型

    public int softInputMode;  

    一共定义了13种键盘在窗口中的显示方法。

    public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
    public static final int SOFT_INPUT_STATE_UNCHANGED = 1;

    当然, WindowManager的一些其他变量也控制着窗口的显示形式。

    3 应用窗口

    3.1 一般应用窗口

    ActivityThread的主线程ApplicationThread的performLaunchActivity方法会调用Activity的onCreate方法,在onCreate中会调用setContentView等方法加载解析xml资源。从Toast的最简单调用开始,它的调用代码是:
    void makeVisible() {
            if (!mWindowAdded) {
                ViewManager wm = getWindowManager(); // 获取的是WindowManagerImpl对象
                wm.addView(mDecor, getWindow().getAttributes()); //  PhoneWindow
                mWindowAdded = true;
            }
            mDecor.setVisibility(View.VISIBLE);
        }

    getAttributes最后获取的默认type类型是TYPE_APPLICATION。

    3.2 Dialog

    Dialog是一系列XXXDialog的基类,我们可以new任意Dialog或者通过Activity提供的 onCreateDialog(……)、onPrepareDialog(……)和showDialog(……)等方法来管理我们的Dialog,但是究 其实质都是来源于Dialog基类,所以我们对于各种XXXDialog来说只用分析Dialog的窗口加载就可以了。

    Dialog构造方法如下,

    Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
            if (createContextThemeWrapper) {
                if (themeResId == 0) {
                    final TypedValue outValue = new TypedValue();
                    context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
                    themeResId = outValue.resourceId;
                }
                mContext = new ContextThemeWrapper(context, themeResId);
            } else {
                mContext = context; 
    //mContext已经从外部传入的context对象获得值(一般是个Activity)!!!非常重要,先记住!!!
            }
    
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    
            final Window w = new PhoneWindow(mContext); // 创建新的Window
            mWindow = w;
            w.setCallback(this);
            w.setOnWindowDismissedCallback(this);
            w.setWindowManager(mWindowManager, null, null);
            w.setGravity(Gravity.CENTER);
    
            mListenersHandler = new ListenersHandler(this);
        }

    看看show方法,

    public void show() {
            if (mShowing) {
                if (mDecor != null) {
                    if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                        mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
                    }
                    mDecor.setVisibility(View.VISIBLE);
                }
                return;
            }
    
            mCanceled = false;
            
            if (!mCreated) {
                dispatchOnCreate(null);
            }
    
            onStart();
            mDecor = mWindow.getDecorView();
    
            if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                final ApplicationInfo info = mContext.getApplicationInfo();
                mWindow.setDefaultIcon(info.icon);
                mWindow.setDefaultLogo(info.logo);
                mActionBar = new WindowDecorActionBar(this);
            }
    
            WindowManager.LayoutParams l = mWindow.getAttributes();
             //和上面分析的Activity一样type为TYPE_APPLICATION
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
                WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
                nl.copyFrom(l);
                nl.softInputMode |=
                        WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
                l = nl;
            }
    
            try {
                mWindowManager.addView(mDecor, l);
    //把一个View添加到Activity共用的windowManager里面去
                mShowing = true;
        
                sendShowMessage();
            } finally {
            }
        }

    可以看见Dialog的新Window与Activity的Window的type同样都为TYPE_APPLICATION,上面介绍 WindowManager.LayoutParams时TYPE_APPLICATION的注释明确说过,普通应用程序窗口 TYPE_APPLICATION的token必须设置为Activity的token来指定窗口属于谁。所以可以看见,既然Dialog和 Activity共享同一个WindowManager(也就是上面分析的WindowManagerImpl),而WindowManagerImpl 里面有个Window类型的mParentWindow变量,这个变量在Activity的attach中创建WindowManagerImpl时传入 的为当前Activity的Window,而当前Activity的Window里面的mAppToken值又为当前Activity的token,所以 Activity与Dialog共享了同一个mAppToken值,只是Dialog和Activity的Window(PhoneWindow)对象不同。

    为什么一定需要Activity的token 呢,禁止在当前activity中弹出另外一个activity的dialog,因为dialog有时候需要交互的,不能像toast一样(toast无交互).

    所以传进去的context对象一定是Activity,如果是其他组件(Service)的context会报错。

    4 子窗口

    PopWindow是android系统中一个典型的子窗口,它的创建也依赖于Activity。

    例如各种菜单(PopupMenu)都是利用PopWindow来实现的。

    PopupWindow与Dialog一个不同点是PopupWindow是一个阻塞的对话框,如果你直接在Activity的onCreate等方法中显示它则会报错,所以PopupWindow最好另开启一个新线程去调用。

       PopupWindow一个构造函数如下,

    public PopupWindow(View contentView, int width, int height, boolean focusable) {
            if (contentView != null) {
                mContext = contentView.getContext();//最终这个mContext实质是Activity
               mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            }   // WindowManager
    
            setContentView(contentView); // 初始化赋值
            setWidth(width);
            setHeight(height);
            setFocusable(focusable);
        }

    显示时,最后都会调用showAsDropDown方法,

    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
            if (isShowing() || mContentView == null) {
                return;
            }
    
            TransitionManager.endTransitions(mDecorView);
    
            registerForScrollChanged(anchor, xoff, yoff, gravity);
    
            mIsShowing = true;
            mIsDropdown = true;
    
           final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
               // 
            preparePopup(p);
    
            final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity);
            updateAboveAnchor(aboveAnchor);
    
            invokePopup(p);
        }

    createPopupLayoutParams方法会新建一个WindowManager.LayoutParams对象,然后变量type赋值为mWindowLayoutType,

    private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
    private void invokePopup(WindowManager.LayoutParams p) {
            if (mContext != null) {
                p.packageName = mContext.getPackageName();
            }
            final PopupDecorView decorView = mDecorView;
            decorView.setFitsSystemWindows(mLayoutInsetDecor);
            setLayoutDirectionFromAnchor();
            mWindowManager.addView(decorView, p);
            if (mEnterTransition != null) {
                decorView.requestEnterTransition(mEnterTransition);
            }
        }

    PopWindow中没有像Activity及Dialog一样new新的Window, 完全使用了Activity的Window与WindowManager。

    5 系统窗口

    系统窗口的种类很多,以Toast为例来论述,

    首先看Toast的构造方法,

    public Toast(Context context) {
            mContext = context;
            mTN = new TN();
            mTN.mY = context.getResources().getDimensionPixelSize(
                    com.android.internal.R.dimen.toast_y_offset);
            mTN.mGravity = context.getResources().getInteger(
                    com.android.internal.R.integer.config_toastDefaultGravity);
        }

    内部类TN构造方法如下, 

    TN() {
                // XXX This should be changed to use a Dialog, with a Theme.Toast
                // defined that sets up the layout params appropriately.
                final WindowManager.LayoutParams params = mParams;
                params.height = WindowManager.LayoutParams.WRAP_CONTENT;
                params.width = WindowManager.LayoutParams.WRAP_CONTENT;
                params.format = PixelFormat.TRANSLUCENT;
                params.windowAnimations = com.android.internal.R.style.Animation_Toast;
                params.type = WindowManager.LayoutParams.TYPE_TOAST;
                params.setTitle("Toast");
                params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
            }

    主要是为WindowManager.LayoutParams中的变量赋值, type赋值为

    params.type = WindowManager.LayoutParams.TYPE_TOAST;

    显示时,调用TN的handleShow方法,如下,

    public void handleShow() {
                if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                        + " mNextView=" + mNextView);
                if (mView != mNextView) {
                    // remove the old view if necessary
                    handleHide();
                    mView = mNextView;
                    Context context = mView.getContext().getApplicationContext();
                    String packageName = mView.getContext().getOpPackageName();
                    if (context == null) {
                        context = mView.getContext();
                    }
                    mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
                    // We can resolve the Gravity here by using the Locale for getting
                    // the layout direction
                    final Configuration config = mView.getContext().getResources().getConfiguration();
                    final int gravity = Gravity.getAbsoluteGravity(mGravity, config.getLayoutDirection());
                    mParams.gravity = gravity;
                    if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
                        mParams.horizontalWeight = 1.0f;
                    }
                    if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
                        mParams.verticalWeight = 1.0f;
                    }
                    mParams.x = mX;
                    mParams.y = mY;
                    mParams.verticalMargin = mVerticalMargin;
                    mParams.horizontalMargin = mHorizontalMargin;
                    mParams.packageName = packageName;
                    if (mView.getParent() != null) {
                        if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                        mWM.removeView(mView);
                    }
                    if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
                    mWM.addView(mView, mParams);
                    trySendAccessibilityEvent();
                }
            }

    和前2种窗口内型不同的是,系统窗口不依赖于Activity而存在,并且由系统服务统一管理,只是一个通知提示作用,并不会和Activity进行交互。

    在使用Toast时context参数尽量使用getApplicationContext(),可以有效的防止静态引用导致的内存泄漏。

    6 addView方法

    mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);

    通过这种方法获取的服务都是WindowManagerImpl对象,其addView方法如下,

    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
            android.util.SeempLog.record_vg_layout(383,params);
            applyDefaultToken(params);
            mGlobal.addView(view, params, mDisplay, mParentWindow);
        }

    直接调用WindowManagerGlobal的

    public void addView(View view, ViewGroup.LayoutParams params,
                Display display, Window parentWindow) {
            if (view == null) {
                throw new IllegalArgumentException("view must not be null");
            }
            if (display == null) {
                throw new IllegalArgumentException("display must not be null");
            }
            if (!(params instanceof WindowManager.LayoutParams)) {
                throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
            }
    
            final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
            if (parentWindow != null) {
                parentWindow.adjustLayoutParamsForSubWindow(wparams);
            } else {
                // If there's no parent, then hardware acceleration for this view is
                // set from the application's hardware acceleration setting.
                final Context context = view.getContext();
                if (context != null
                        && (context.getApplicationInfo().flags
                                & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
                    wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
                }
            }
    
            ViewRootImpl root;
            View panelParentView = null;
    
            synchronized (mLock) {
                // Start watching for system property changes.
                if (mSystemPropertyUpdater == null) {
                    mSystemPropertyUpdater = new Runnable() {
                        @Override public void run() {
                            synchronized (mLock) {
                                for (int i = mRoots.size() - 1; i >= 0; --i) {
                                    mRoots.get(i).loadSystemProperties();
                                }
                            }
                        }
                    };
                    SystemProperties.addChangeCallback(mSystemPropertyUpdater);
                }
    
                int index = findViewLocked(view, false);
                if (index >= 0) {
                    if (mDyingViews.contains(view)) {
                        // Don't wait for MSG_DIE to make it's way through root's queue.
                        mRoots.get(index).doDie();
                    } else {
                        throw new IllegalStateException("View " + view
                                + " has already been added to the window manager.");
                    }
                    // The previous removeView() had not completed executing. Now it has.
                }
    
                // If this is a panel window, then find the window it is being
                // attached to for future reference.
                if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
                        wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                    final int count = mViews.size();
                    for (int i = 0; i < count; i++) {
                        if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
                            panelParentView = mViews.get(i);
                        }
                    }
                }
    
                root = new ViewRootImpl(view.getContext(), display); // 初始化
                view.setLayoutParams(wparams);
                mViews.add(view);
                mRoots.add(root);
                mParams.add(wparams);
            }
    
            // do this last because it fires off messages to start doing things
            try {
                root.setView(view, wparams, panelParentView);
            } catch (RuntimeException e) {
                // BadTokenException or InvalidDisplayException, clean up.
                synchronized (mLock) {
                    final int index = findViewLocked(view, false);
                    if (index >= 0) {
                        removeViewLocked(index, true);
                    }
                }
                throw e;
            }
        }

    最后的setView方法会调用performTraversals方法完成View的测量,确定位置以及显示,这样一个窗口就显示出来了。

    展开全文
  • 几种窗口类型

    千次阅读 2013-06-02 16:53:11
     MFC提供三种类型的框架窗口:单文档窗口,多文档窗口(MDI),对话框。在AppWizard的第一个对话框中,就提供了选项,让用户选择应用程序是基于单文档、多文档还是对话框的。MFC单文档窗口一次只能打开一个文档框架...

    框架窗口为应用程序的用户界面提供结构框架,它是应用程序的主窗口,负责管理其包容的窗口,一个应用程序的最顶层的框架窗口是应用程序启动时创建的第一个窗口。
      MFC提供三种类型的框架窗口:单文档窗口,多文档窗口(MDI),对话框。在AppWizard的第一个对话框中,就提供了选项,让用户选择应用程序是基于单文档、多文档还是对话框的。MFC单文档窗口一次只能打开一个文档框架窗口,而MDI应用程序运行时,在应用程序的一个实例中打开多个文档框架窗口,这些窗口称作子窗口(Child Window)。这些文档可以是同一类型的,也可以是不同类型的。如Visual Studio就可以打开资源文件窗口和源程序窗口等不同类型的窗口。此时,激活不同类型的MDI子窗口,菜单也将相应变化。
      MFC提供了三个类CFrameWnd、CMDIFrameWnd、CMDIChildWnd和CDialog 分别用于支持单文档窗口、多文档窗口和对话框。

    CFrameWnd
      用于SDI框架窗口,形成单个文档及其视的边框。框架窗口既是应用程序的主框架窗口,也是当前文档对应的视图的边框。

    CMDIFrameWnd
      用于MDI应用程序的主框架窗口。主框架窗口是所有MDI文档窗口的容器,并与它们共享菜单条。MDI框架窗口是出现在桌面中的顶层窗口。

    CMDIChildWnd
      用于在MDI主框架窗口中显示打开的各个文档。每个文档及其视都有一个MDI子框架窗口,子框架窗口包含在MDI主框架窗口中。子框架窗口看起来类似一般的框架边框窗口,但它是包含在主框架窗口中,而不是位于桌面的,并且为主窗口所裁剪。而且MDI子窗口没有自己的菜单,它与主MDI框架窗口共享菜单。

    CDialog
      对话框是一种特殊类型的窗口,它的边框一般不可以调整,而且内部包含一些控件窗口。有关对话框作为主窗口的技术可以参见下一章。

      要生成一个单文档窗口,主窗口就必须从CFrameWnd派生;要生成一个多文档窗口,主窗口就必须从CMDIFrameWnd派生,而且其中的子窗口必须从CMDIChildWnd派生出来;而基于对话框的窗口程序就要从CDialog派生出主窗口类。

    子窗口
      
    子窗口就是具有WS_CHILD风格的窗口,且一定有一个父窗口。所有的控件都是子窗口。子窗口可以没有边框。子窗口被完全限制在父窗口内部。

    父窗口
      父窗口就是拥有子窗口的窗口。

    弹出式窗口
      
    具有WS_POPUP风格,它可以没有父窗口。这种窗口几乎什么都没有,可看作一个矩形区域。

    3.5.2窗口的创建

    窗口的创建分为两步:第一步是用new创建一个C++的窗口对象,但是此时只是初始化窗口的数据成员,并没有真正创建窗口(这一点与一般的对象有所不同)。

    //第一步:创建一个C++对象,其中CMainFrame是从CFrameWnd派生的对象。

    CMainFrame* pMyFrame=new CMainFrame();//用new操作符创建窗口对象

    CMainFrame MyFrame;//定义一个窗口对象,自动调用其构造函数

    第二步是创建窗口。CFrameWnd的Create成员函数把窗口给做出来,并将其HWND保存在C++对象的公共数据成员m_hWnd中。

    //第二步:创建窗口

    pMyFrame->Create(NULL,“My Frame Window”);

    MyFrame.Create(NULL,“My Frame Window”);

    Create函数的原形如下:

    BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

      Create函数第一个参数为窗口注册类名,它指定了窗口的图标和类风格。这里我们使用NULL做为其值,表明使用缺省属性。第二个参数为窗口标题。其余几个参数指定了窗口的风格、大小、父窗口、菜单名等。

      这个函数看起来比较复杂,对于CFrameWnd派生出来的窗口,我们可以使用LoadFrame从资源文件中创建窗口,它只需要一个参数。

    pMyFrame->LoadFrame(IDR_FRAME);

    LoadFrame使用该参数从资源中获取许多默认值,包括主边框窗口的标题、图标、菜单、加速键等。但是,在使用LoadFrame时,必须确保标题字符串、图标、菜单、加速键等资源使用同一个ID标识符(在本例中,我们使用IDR_FRAME)。

    提示:在Hello程序的InitInstance中我们看不到创建窗口的过程。实际上,在

    pDocTemplate = new CSingleDocTemplate(

    IDR_MAINFRAME,

    RUNTIME_CLASS(CHelloDoc),

    RUNTIME_CLASS(CMainFrame), // main SDI frame window

    RUNTIME_CLASS(CHelloView));

      AddDocTemplate(pDocTemplate); 程序片段中,我们看到,CSingleDocTemplate构造函数的第二个参数就是IDR_MAINFRAME。在构造函数内部,已经通过调用m_pMainWnd->LoadFrame(IDR_MAINFRAME),完成了应用程序主窗口的创建过程。
      在InitInstance中,创建完窗口后,窗口调用ShowWindow成员函数来显示窗口。ShowWindow带一个参数,指示窗口以何种方式显示(最大化、最小化或一般)。缺省方式为SW_SHOW,但实际上我们经常希望应用程序启动时窗口最大化,此时可以将该参数该为SW_SHOWMAXMIZED,即调用

    m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

      在MainFrm.cpp中,我们还看到CMainFrame类有一个OnCreate方法。OnCreate成员函数定义如清单3.3。当调用Create或CreateEx时,操作系统会向窗口发送一条WM_CREATE消息。这一函数就是用来响应WM_CREATE消息的。

    清单3.3 OnCreate成员函数定义

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

    {

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

    return -1;

     

    if (!m_wndToolBar.Create(this) ||

    !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

    {

    TRACE0("Failed to create toolbar\n");

    return -1; // fail to create

    }

    if (!m_wndStatusBar.Create(this) ||

    !m_wndStatusBar.SetIndicators(indicators,

    sizeof(indicators)/sizeof(UINT)))

    {

    TRACE0("Failed to create status bar\n");

    return -1; // fail to create

    }

    // TODO: Remove this if you don't want tool tips or a resizeable toolbar

    m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |

    CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

    // TODO: Delete these three lines if you don't want the toolbar to

    // be dockable

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

    EnableDocking(CBRS_ALIGN_ANY);

    DockControlBar(&m_wndToolBar);

    return 0;

    }

      在OnCreate函数中,首先调用CFrameWnd的缺省处理方法OnCreate完成窗口创建工作。后面是应用程序主窗口的特定工作,在上面程序中,创建了工具条和状态栏(有关工具条和状态栏编程参见下一章有关内容)。可以在此处加入一些初始化工作,如从INI文件中载入设置,显示Splash Window(启动画面)等。

    3.5.3 注册窗口

      在传统的Windows C程序中,送给一个窗口的所有消息是在它的窗口函数中处理的。把一个窗口同它的窗口函数联系起来的过程称为注册窗口类。注册窗口包括对窗口指定一个窗口函数(给出窗口函数的指针)以及设定窗口的光标、背景刷子等内容。一个注册窗口类可以被多个窗口共享。注册窗口通过调用API函数RegisterClass来完成。
      在MFC下,框架提供了缺省的自动窗口注册过程。框架仍然使用传统的注册类,而且提供了几个标准的注册类,它们在标准的应用程序初始化函数中注册。调用AfxRegisterWndClass全局函数就可以注册附加的窗口类,然后把已经注册的类传给CWnd的Create成员函数。用户可以定制自己的注册过程,以提供一些附加的特性。比如设置窗口的图标、背景、光标等。下面是注册窗口的例子。

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

    {

    // TODO: Modify the Window class or styles here by modifying

    // the CREATESTRUCT cs

    UINT ClassStyle=CS_VREDRAW|CS_HREDRAW;

    cs.style=cs.style&(~FWS_ADDTOTITLE);

    cs.lpszClass = AfxRegisterWndClass(ClassStyle,

    AfxGetApp()->LoadStandardCursor(IDC_ARROW),

    (HBRUSH)(COLOR_WINDOW+1),//for brush

    AfxGetApp()->LoadIcon(IDR_MAINFRAME));

    return TRUE;

    }

      注册窗口在CFrameWnd的PreCreateWnd方法中完成。从成员函数名字PreCreateWindow中就可以看出来,注册窗口的工作必须在调用Create函数创建窗口之前完成。其中cs.style=cs.style&(~FWS_ADDTOTITLE)指定窗口标题风格,关闭自动添加文档标题的功能。AfxRegisterWndClass指定窗口使用箭头光标、背景刷子使用比窗口颜色标号大一的颜色、图标使用IDR_MAINFRAME标识符指定的图标(当然也可以使用其它图标)。用上面的程序段替换Hello程序MainFrm.cpp中的PreCreateWindow成员函数定义,并重新编译和运行程序。此时,窗口标题变成了Hello,原来令人讨厌的“Untitled-”没有了,因为窗口风格中关闭自动添加当前文件名的风格。

    3.5.4 关闭和销毁窗口

      框架窗口不仅维护窗口的创建,还管理着窗口的关闭和销毁过程。关闭窗口时,操作系统依次向被关闭的窗口发送WM_CLOSE和WM_DESTROY消息。WM_CLOSE消息的缺省处理函数OnClose将调用DestroyWindow,来销毁窗口;最后,框架调用窗口的析构函数作清理工作并删除C++窗口对象。
      不要使用C++的delete操作符来销毁框架窗口,而应当采用CWnd的DestroyWindow成员函数来销毁。DestroyWindow首先删除子窗口,再删除窗口本身。若窗口以变量方式产生(即在堆栈上分配内存),该窗口对象会被自动清除。若对象是用new操作符创建的(也就是在堆上分配内存的),则需要用户自己处理。有关DestroyWindow问题在第五章对话框技术中还要作进一步解释。

    OnClose()常用功能:保存窗口的一些状态、工具条状态,提示保存未保存的数据等等。

    void CMainFrame::OnClose()

    {

    SaveBarState( "MyDockState" );//保存工具条状态

    CFrameWnd::OnClose();

    }

    3.5.5 窗口激活

      活动窗口必定是一个没有父窗口的顶层窗口,包括框架窗口和对话框。当顶层窗口被激活时,Windows向窗口发送WM_ACTIVATE消息,对此消息的缺省处理是将活动窗口设为有输入焦点。
      输入焦点用于表示哪个窗口有资格接收键盘输入消息。带有输入焦点的窗口或是一个活动窗口,或者是该活动窗口的子窗口。当一个顶层窗口获得输入焦点时,Windows向该窗口发送WM_SETFOCUS消息,此窗口可将输入焦点重定位到它的子窗口上。子窗口不会自动获得输入焦点。失去输入焦点的窗口会收到WM_KILLFOCUS消息。当子窗口拥有输入焦点时,父窗口就不会处理键盘输入了。  

    展开全文
  • 窗口部件及窗口类型

    千次阅读 2017-07-13 17:54:14
    命令行: qmake -projct qmake make Log调试法: 在代码中加入一定的打印语句 打印程序状态和关键变量的值 断点调试法 ...图形用户界面由不同的窗口窗口组件构成 头文件包含窗口组件,对应Q
  • 常见漏洞类型汇总

    万次阅读 2018-11-06 16:33:57
    常见情况是某用户在论坛发贴,如果论坛没有过滤用户输入的Javascript代码数据,就会导致其他浏览此贴的用户的浏览器会执行发贴人所嵌入的Javascript代码。    (3)DOM跨站(DOM XSS):是一种发生在客户端...
  • Unity常见资源类型

    千次阅读 2019-11-15 17:49:16
    资源工作流程 在Unity项目中有一个固定的文件夹—Assets文件夹。 Assets是放项目需要到的文件资源的,比如:图片文件、3D模型文件(*....还有一些可以在 Unity 中创建的资源类型,例如动画控制器 (Animator Cont...
  • 其中组件的类型包括两大类: 容器类(父组件):用于包含其他的界面组件。 功能类(子组件):用于实现特定的交互功能。 一个GUI包括许多图形组件,其中容器组件就是为了承载别的功能组件,功能组件就是用来提供...
  • ICMP 常见应用有:1. 报告访问失效(报告源主机网络不可达);2. 报告网络拥塞(发送源抑制报文给源主机,降低发送速率);3. 帮助排错(利用 ICMP 回声功能,ping 工具);4. 声明报文超时(TraceRoute 工具,...
  • 窗口部件基础窗口部件QWidget类——是所有用户界面对象的基类,窗口和控件都是直接或间接继承自 QWidget,下面我们来看一个很简单的例子:窗口部件(Widget)——简称部件,是QT中建立界面的主要元素,QT中把没有...
  • hive 窗口函数--常用函数介绍

    千次阅读 2020-07-19 00:25:01
    一、窗口函数概念 窗口函数是一组特殊函数,通过扫描多个输入行来计算每个输出值,为每行数据生成一行结果,可以通过窗口函数来实现复杂的计算和聚合。窗口函数也称为OLAP(Online Analytical Processing)函数,是...
  • PyQt5 GUI编程——窗口类型

    千次阅读 2019-07-09 07:41:27
    窗口类型介绍: 窗口类型包括 QMainWindow QWidget QDialog三类,这三个类都是用来创建窗口的,可以直接使用,也可以继承后使用。 接下来介绍一下这三个类的区别: QMainWindow窗口可以包含菜单栏、工具栏、状态...
  • Android窗口设计之Dialog、PopupWindow、系统窗口的实现

    千次阅读 热门讨论 2020-12-19 16:07:43
        窗口设计之Dialog、PopupWindow、系统窗口的实现 Android应用程序窗口设计系列博客: Android应用程序窗口设计之Window及WindowManager的创建 Android应用程序窗口设计之setContentView布局加载的实现 普法...
  • 窗口
  • Apache Flink窗口的几种实现的类别

    千次阅读 2020-04-16 22:02:16
    DataStream API中包含了Event Time与Process Time时间类型窗口。详细的时间介绍可以看我前一篇文章中的各个窗口时间的概念区分>>,同时对应的也有Event与Process相关的Trigger进行计算的触发。 滑动窗口 滑动窗口...
  • Windows 中常见的消息类型及其说明

    千次阅读 2018-09-06 22:19:11
    消息类型 消息说明 参数说明 WM_CREATE 当创建一个窗口时响应 WM_DESTOROY 当摧毁一个窗口时响应 WM_MOVE 当窗口被移动时响应 WM_SIZE 当窗口被改变大小时响应 ...
  • 目录 问题 解决 问题 如果我们在electron工程中创建了多个BrowserWindow对象,...除了自己的主窗口还有四个其他窗口,看着真的不爽! 那怎么能让他们不显示呢? 那就是 win.setSkipTaskbar() 。 方法原型:...
  • 对于多窗口的情况,一般有两种解决方法:一种是主窗口获取子窗口中控件的属性,另一种是通过信号与槽机制,一般是子窗口通过发射信号的形式传递数据,主窗口的槽函数获取这些数据。
  • 控件本身也是窗口,因此还具有窗口类型,如让控件创建后即可见,可给控件WS_VISIBLE, 通常还具有WS_CHILD属性 const RECT& rect 矩形区域,可以是CRect类型,也可是Rect结构体。可直接由CRect构造,如CRect (0,...
  • PB窗口类型详细总结

    千次阅读 2008-03-31 20:54:00
    按照对消息响应的方式,窗口分为模式窗口和非模式窗口两大类。在模式窗口中的操作没有...最常见的非模式窗口例子是Excel中的sheet。 要创建窗口,必须指明窗口的显示样式,如边框、是否显示控制按钮、是否能够浮动等。
  • 窗口函数的基本使用方法

    千次阅读 多人点赞 2019-07-08 12:16:18
    窗口函数简介 窗口函数又名开窗函数,属于分析函数的一种。用于解决复杂报表统计需求的功能强大的函数。窗口函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组...
  • [Flink]Flink1.3 Stream指南三 窗口分配器

    千次阅读 2017-10-24 11:11:36
    1.4版本:Flink1.4 窗口概述Windows(窗口)是处理无限数据流的核心。Windows将流分解成有限大小的"桶",在上面我们可以进行计算。本文档重点介绍如何在Flink中处理窗口,以及如何从它提供的功能中获得最大...
  • MIME 类型大全,你值得收藏

    千次阅读 2020-08-02 16:34:00
    多用途Internet邮件扩展(MIME)类型 是一种标准化的方式来表示文档的性质和格式。 它在IETF RFC 6838中进行了定义和标准化。互联网号码分配机构(IANA)是负责跟踪所有官方MIME类型的官方机构,您可以在媒体类型...
  • MFC代码修改窗口属性

    千次阅读 2016-06-16 17:50:43
    在创建窗口时属性页中的属性都是可以通过代码来动态设置的 主要用到两个函数 GetWindowLongPtr(__in HWND hWnd,//窗口句柄  __in int nIndex //要获取的类型 ); SetWindowLongPtr(  __in HWND hWnd, //窗口句柄...
  • Windows编程 Win32API中常见的数据类型

    千次阅读 2015-12-31 15:20:28
    Win32API有一套和C\C++基本数据类型不同的数据类型. C\C++语言的数据类型有如下几个缺陷: 数据类型平台相关,在不同平台上,同一个数据类型可能占用不同的空间大小。典型的,在16位系统上,int类型和short int...
  • vim调整窗口大小 vim中常见的工作流程是使用多个窗口同时查看和编辑各种文件。 但是,一旦打开,每个窗口的大小通常保持不变,除非明确调整大小。 更好的工作流程是使聚焦窗口的宽度自动扩展。 代码 这个行为...
  • windows窗口分析,父窗口,子窗口,所有者窗口

    万次阅读 多人点赞 2016-12-14 11:50:57
    (本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++、Windows编程及MFC经验,还得有一定动手能力。文中可能出现一些术语不统一的现象,比如“子窗口”,有...
  • Flink流处理之窗口算子分析

    万次阅读 2016-10-29 19:40:20
    窗口算子WindowOperator是窗口机制的底层实现,它几乎会牵扯到所有窗口相关的知识点,因此相对复杂。本文将以由面及点的方式来分析WindowOperator的实现。
  • ...MATLAB用户界面的熟悉(内容,特点,标题栏,功能区,选项卡,工具栏命令行窗口,命令历史记录窗口,当前目录窗口,工作区窗口,图像窗口
  • Windows窗口及对话框

    千次阅读 2016-02-18 22:19:46
    1、Windows窗口介绍    在Windows系统中,每个窗口对象都对应有一个数据结构,形成一个list链表。系统的窗口管理器通过这个list来获取窗口信息和管理窗口,这个数据结构中有四个数据用来构建list,即child、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 179,668
精华内容 71,867
关键字:

常见的窗口类型