如何使用win32 API重新绘制子窗口的控件 [英] how to repaint child window's controls using win32 API

查看:128
本文介绍了如何使用win32 API重新绘制子窗口的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主窗口,它有一个子窗口,而子窗口又有一个子窗口和一个按钮。当我从任务栏恢复窗口时,按钮和第三个子窗口拒绝显示。我尝试首先在孩子身上使用 RedrawWindow(),然后是孩子和按钮但是没有用。到目前为止,看起来子窗口与其子窗口之间没有任何联系,因为父母负责重新绘制其子女,但孩子没有义务。在父(主窗口)重绘期间,如何重新绘制子窗口的控件/子窗口(子窗口)。那是在使用Win32 API恢复父级之后。



我创建了一个控件类作为应用程序的入口点并监督所有其他类(屏幕类 - 用于GUI ,数据库类...),Screen类中包含所有子创建代码。具体如下:



I have a main window which has a child window which in turn have a child window and a button. When i restore the window from taskbar the button and third child window refuse to display. I tried using RedrawWindow() on the child first, and then the grand child and the button but didnt work. So far it looks like there is no connection between the child window and its child cos the parent is responsible for repainting its child, but the child has no duty. How do i repaint child window's controls / child window (child of a child), during parent (main window) repaint. That is after restore of parent using Win32 API.

I created a control class as the entry point of the app and to oversee all other classes(Screen class- for GUI, Database class...), the Screen class have all the child creation codes in it. This is how:

//MainControl Class

#include <tchar.h>
#include "Screen.h"
#include <stdlib.h>
#include "FreeImage.h"
#pragma comment(lib, "user32")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"FreeImage.lib")




const char g_szClassName[] = "myWindowClass";
Screen display;
HWND welcomScreenHndl, menuScreenHndl, butt;

// Function prototypes
LRESULT CALLBACK WndProc(HWND hwnd, UINT messages, WPARAM wParam, LPARAM lParam);




int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
					int nCmdShow){
	
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;
	
	// Registering the Window Class.
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = g_szClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	
	if(!RegisterClassEx(&wc)){
		MessageBox(NULL, "Window Registration Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	
	// Creating the Window.
	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName,
		"Prison Management System",
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
        100, 30, 750, 700, NULL, NULL, hInstance, NULL);
	
	if(hwnd == NULL){
		MessageBox(NULL, "Window Creation Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	
	
	// Creating Other Windows with Scree class object.
	welcomScreenHndl = display.welcomeScreen(hwnd, hInstance);//Child to Main Window
	menuScreenHndl = display.menuScreen(welcomScreenHndl, hInstance);//grand child
	
	
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	// The message loop.
	while(GetMessage(&Msg, NULL, 0, 0) > 0){
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}


Here is the Screen class:  // Screen Class

#include <tchar.h>
#include <windows.h>



class Screen{
	
	char winClassName[20];
public:
	
	HWND welcomeScreen(HWND parent, HINSTANCE hInstance);
	HWND menuScreen(HWND parent, HINSTANCE hInstance);
	
};



HWND Screen::welcomeScreen(HWND parent, HINSTANCE hInstance){
	
		GetClassName(parent, winClassName, 20);
		
		HWND hwndpan = CreateWindowEx( WS_EX_CLIENTEDGE,
				winClassName,
				"",
				WS_CHILD | WS_VISIBLE | CS_HREDRAW | CS_VREDRAW,
				0, 20, 745, 695,
				parent, NULL, hInstance/*GetModuleHandle(NULL)*/, NULL);
				
		
		return hwndpan;
	}
	
	HWND Screen::menuScreen(HWND parent, HINSTANCE hInstance){
	
		HWND hwndpan = CreateWindowEx( WS_EX_CLIENTEDGE,
				winClassName,
				"",
				WS_CHILD | WS_VISIBLE | CS_HREDRAW | CS_VREDRAW,
				0, 100, 745, 695,
				parent, NULL, hInstance/*GetModuleHandle(NULL)*/, NULL);
		
		return hwndpan;
	}

推荐答案

我试图打开 CLASS FILE s使用 NetBeans 但失败了。



记事本 Word 也无济于事。 然而,看到你的应用程序在行动中似乎让我明白了。



我要确认一下:



在你的 JAVA 程序,类 welcomeScreen 是登录窗口, menuScreen 窗口是具有按钮的面板左边是右边的手袖口的照片吗?



如果是这样的话,那么至少可以说总体方法是不常见的。即使你设法以某种方式解决这个问题,它也会导致未来很大的复杂化。



这是我建议的概念你:



1.创建主窗口。



2.在其中创建 ALL 你需要的控件(你在 WM_CREATE 处理程序的主窗口窗口过程中执行此操作)。



3.使用 ShowWindow API显示登录和退出按钮,其他按钮隐藏(再次,你在 WM_CREATE 处理程序)。



4.可以绘制 JAVA 应用程序主窗口中的图片,橙色线条和文字使用 GDI ,使用 BitBlt API,你应该在你的中这样做WM_PAINT 处理程序。 然而,我会使用静态控件 SS_BITMAP 来显示图片,只需隐藏/在 WM_CREATE 处理程序中显示它们,稍后在必要时显示它们。在这两种情况下,您都必须将 JPEG 图像转换为 BMP ,除非您希望使用 GDI + 这也很好。



5.对于 JAVA 应用程序(如View Prisoner选项),我会创建对话框。对于简单消息(信息/错误),请使用 MessageBox API。对话框是用资源编辑器制作的,它应该随你的IDE一起提供,但以下是免费的:

http://www.resedit.net/ [ ^ ]



6.按钮点击等事件在 WM_COMMAND handler,从那里你可以启动你想要的对话框。



7.至于数据库通信, ADO.NET 可能有用,但也许你应该问一个比我更有经验的人提出建议。



既然你刚开始(我做了这个假设)根据你之前的评论),我想建议你一个简单有效的 WIN32 教程:



< a href =http://www.winprog.org/tutorial/> http://www.winprog.org/tutorial/ [ ^ ]



下载源代码和PDF格式!



通过它应该教你足够,所以你可以翻译大部分您现有的应用程序 C ++



完成后,浏览<$​​ c $ c> MSDN
文档将帮助您完成剩下的工作(主要用于 JPEG 图像,其余的可以从教程中找到)。



我建议你先完成整个教程,然后实现我建议的设计,或者你最适合的方式。


如果你遇到困难,你可以随时提出另一个问题。 您也可以给我留言,我会尽力帮助您。



我知道这不是回答你的预期,但我相信这种方法会比你选择的方法好得多。



希望这个答案能帮到你。



祝你好运。



祝你好运。
I have tried to open CLASS FILEs with NetBeans but have failed.

Notepad and Word didn't help either. However, seeing your application "in action" seems to made things clear to me.

Let me just confirm this:

In your JAVA program, class welcomeScreen is the login window, and menuScreen window is the panel that has buttons from the left and a picture of the hand-cuffs on the right?

If that is so, then total approach is "not the usual one" to say the least. It will lead to great complications in the future, even if you manage to solve this problem somehow.

This is the concept I suggest to you:

1. Create main window.

2. In it create ALL the controls you need ( you do this in the main window's window procedure in the WM_CREATE handler ).

3. Using ShowWindow API show the login and exit button, other buttons hide ( again, you do this in WM_CREATE handler ).

4. Pictures, orange lines and text in your JAVA application's main window can be drawn with the use of GDI, with a BitBlt API, and you should do that in your WM_PAINT handler. However, I would use static controls with SS_BITMAP to display pictures, and simply hide/show them in WM_CREATE handler, showing them later on when necessary. In both cases you will have to convert your JPEG images to BMP, unless you wish to use GDI+ which is fine too.

5. For message boxes in your JAVA application ( like View Prisoner option ), I would create dialog boxes. For simple messages ( information/errors ), use MessageBox API. Dialog boxes are made with resource editor and it should come with your IDE, but just in case here is the free one:
http://www.resedit.net/[^]

6. Events, such as button clicks are handled in WM_COMMAND handler, from where you can launch dialog boxes you want.

7. As for database communication, ADO.NET could be useful, but maybe you should ask someone more experienced than me for an advice about that.

Since you are starting out ( I made this assumption based on your previous comments ), I would like to suggest you a simple and effective WIN32 tutorial:

http://www.winprog.org/tutorial/[^]

Download both source code and PDF!

Going through it should teach you enough so you can translate most of your existing application to C++.

After you go through it, browsing through MSDN documentation will help you do the rest ( mostly for your JPEG images, the rest you can figure out from the tutorial ).

I suggest you to first go through the entire tutorial, and then to implement the design I have suggested, or the way you suit best.

If you get stuck you can always ask another question here. You can also leave me a comment and I will try to help you as much as I can.

I know that this is not the answer you have expected, but I believe that this approach will be much better than the one you have chose.

Hopefully this answer will help you.

Wish you best of luck.

Best regards.


我整晚都快速看了一眼。



也许这段代码对你有用。我已经用它来演示(a)在决定采取哪个动作之前检查对话框的返回值。 (b)打开多个窗口,然后每个对话框可以打开另一个对话框或自行关闭。

(c)一种使用DialogBoxParam将信息传递给正在创建的对话框的方法,以便可以初始化以特定的方式。



主对话框的3个按钮只是打开子对话框或退出程序。我使用的子对话框被设计为具有褐色背景。点击登录按钮后,您将获得其中一个。如果你点击OK,这个子对话框将创建另一个自身副本,或者如果你点击关闭将自动关闭。



至于'测试'按钮,打开在同一个对话框中,但传递信息,如窗口标题和背景颜色。点击此对话框上的确定将打开另一个默认对话框 - 也就是说,新的对话框将具有棕色背景。



您可以轻松(a)将图像转换为BMP格式并使用LoadImage或(b)使用GDI +通过从磁盘文件填充Gdiplus :: Bitmap对象来打开jpg / png图像。您可以使用以下函数加载Windows本机支持的任何内容。只是不要忘记在你打电话之前初始化Gdi +!



I had a quick look and play around the other night.

Perhaps this code will be of some use to you. I've used it to demonstrate (a) checking for the return value of a dialog, before deciding which action to take. (b) open multiple windows, each dialog may then open another dialog or be closed itself.
(c) a way of using DialogBoxParam to pass info to the dialog being created, such that it can be initialized in a particular way.

The main dialog's 3 buttons just open child dialogs or exit the program. The child dialog box I'e used has been designed to have a brownish background. You get one of these when you hit the Login button. This child dialog will then create another copy of itself if you hit OK, or will close itself if you hit close.

As for the 'Test' button, that opens up the same dialog, but passes it info such as the window title and the background colour. Hitting OK on this dialog will open up another of the 'default' dialog boxes - that is to say, the new one will have a brown background.

You can easily (a) convert the images to BMP format and use LoadImage or (b) use GDI+ to open jpg/png images by filling a Gdiplus::Bitmap object from a disk file. You can use the following function to load anything natively supported by windows. Just don't forget to initialize Gdi+ before you call it!

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
HBITMAP mLoadImageFile(wchar_t *filename)
{
    HBITMAP result = NULL;
    Bitmap bitmap(filename, false);
    bitmap.GetHBITMAP(0, &result);
    return result;
}





无论如何,这是足够的喋喋不休。这是代码。如果您有任何疑问,请随时询问。



main.cpp



Anyway, that's enough chatter. Here's the code. If you've any questions, feel free to ask.

main.cpp

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"

HINSTANCE hInst;

typedef struct DLGDATA
{
    wchar_t *windowText;
    COLORREF bkgCol;
} *pDlGDATA;

BOOL CALLBACK LoginDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
    {
        HBRUSH bkBrush;
        pDlGDATA refData;
        refData = (pDlGDATA)lParam;
        if (refData != NULL)
        {
            bkBrush = CreateSolidBrush( refData->bkgCol );
            SetProp(hwndDlg, "bkBrush", (HANDLE)bkBrush);
            SetWindowTextW(hwndDlg, refData->windowText );
        }
        else
        {
            bkBrush = CreateSolidBrush( RGB(137, 48, 14) );
            SetProp(hwndDlg, "bkBrush", (HANDLE)bkBrush);
        }
    }
    return TRUE;

    case WM_NCDESTROY:
        {
            HBRUSH bkBrush;
            bkBrush = (HBRUSH) GetProp(hwndDlg, "bkBrush");
            if (bkBrush)
            {
                DeleteObject(bkBrush);
                RemoveProp(hwndDlg, "bkBrush");
            }
        }
        return 0;

    case WM_CLOSE:
    {
        EndDialog(hwndDlg, 0);
    }
    return TRUE;

    case WM_ERASEBKGND:
        {
            HBRUSH mBrush;
            RECT clientRect;
            GetClientRect(hwndDlg, &clientRect);
            mBrush = (HBRUSH) GetProp(hwndDlg, "bkBrush");
            if (mBrush)
                FillRect( (HDC) wParam, &clientRect, mBrush);
            else
                FillRect( (HDC) wParam, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
        }
        return 1;

    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
        case IDOK:
            ShowWindow(hwndDlg, SW_HIDE);
            DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)LoginDlgProc);
            ShowWindow(hwndDlg, SW_SHOW);
            break;

        case IDCANCEL:
            EndDialog(hwndDlg,-2);
            break;
        }
    }
    return TRUE;
    }
    return FALSE;
}

BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
    {
    }
    return TRUE;

    case WM_CLOSE:
    {
        EndDialog(hwndDlg, 0);
    }
    return TRUE;

    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
        case IDC_BUTTON1:
            ShowWindow(hwndDlg, SW_HIDE);
            DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)LoginDlgProc);
            ShowWindow(hwndDlg, SW_SHOW);
            break;

        case IDC_BUTTON2:
            EndDialog(hwndDlg,-2);
            break;

        case IDC_BUTTON3:
            {
                ShowWindow(hwndDlg, SW_HIDE);
                DLGDATA mData;
                mData.bkgCol = RGB(50,200,60);
                mData.windowText = L"lParam-passed data modified dialog";
                DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwndDlg, (DLGPROC)LoginDlgProc, (LPARAM)&mData );
                ShowWindow(hwndDlg, SW_SHOW);
            }
            break;
        }
    }
    return TRUE;
    }
    return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst=hInstance;
    InitCommonControls();
    return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);
}







resource.h




resource.h

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define DLG_MAIN                                100
#define IDD_DIALOG1                             101
#define IDC_BUTTON1                             1000
#define IDC_BUTTON2                             1001
#define IDC_BUTTON3                             1002







resource.rc




resource.rc

// Generated by ResEdit 1.5.11
// Copyright (C) 2006-2012
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
DLG_MAIN DIALOG 0, 0, 277, 230
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Prison Management System"
FONT 8, "Ms Shell Dlg"
{
    CONTROL         "", IDC_STATIC, WC_STATIC, SS_BLACKFRAME, 53, 51, 171, 119
    PUSHBUTTON      "Login", IDC_BUTTON1, 53, 189, 50, 14
    PUSHBUTTON      "Exit", IDC_BUTTON2, 174, 189, 50, 14
    LTEXT           "A computerized prison management system", IDC_STATIC, 67, 27, 142, 8, SS_LEFT
    PUSHBUTTON      "Test", IDC_BUTTON3, 113, 193, 50, 14
}



LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
    DEFPUSHBUTTON   "OK", IDOK, 129, 7, 50, 14
    PUSHBUTTON      "Cancel", IDCANCEL, 129, 24, 50, 14
}



//
// Manifest resources - used to ensure app has winxp (or newer) theming engine enabled.
//  ResEdit can provide a default manifest for you, as presumably can VS. I won't include it
// sine it's generic info not really related to achieving the aims of the application.
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1                  RT_MANIFEST    ".\\manifest.xml"


更好地使用带坐标的InvalidateRect,所以系统可以更好地重绘它=>

http://msdn.microsoft.com/en-us/library/windows/desktop/dd145002(v = vs.85).aspx [ ^ ]
better use InvalidateRect with coordinates, so the system can better redraw it =>
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145002(v=vs.85).aspx[^]


这篇关于如何使用win32 API重新绘制子窗口的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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