显示ComboBox

时间:2016-02-26 07:56:57

标签: c++ winapi combobox

我在WinApi中显示Combobox和另一个控件时遇到问题。我试图创建可以帮助我创建应用程序的c ++类。 每个类包含一个控件和基本操作。 所以我创建了主WinApiElement.h类:

#pragma once

#include <windows.h>

class WinApiElement
{
public:
    virtual LRESULT CALLBACK InteriorWndProc(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
    static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    HWND handle;
};

其中staticWndProc接收消息并将其定向到InteriorWndProc(使用GWLP_USERDATA)。类组件继承类WinApiElement,并包含基本操作:

#pragma once

#include <Windows.h>
#include <Windowsx.h>
#include "WinApiElement.h"
#include "Application.h"
#include "Define.h"

...

class Component : public WinApiElement
{

protected:
    int x;
    int y;
    int width;
    int height;
    int componentNumber;
    bool transparent;
    bool mouseHover;
    bool LButtonDown;
    TRACKMOUSEEVENT trackMouse;

    void Create(WinApiElement* Parent, DWORD dwExStyle, LPCSTR nComponent, DWORD ndwStyle, bool parentWndProc, int nleft = 0, int ntop = 0, int nwidth = 200, int nheight = 100);
    virtual void WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
    LRESULT CALLBACK InteriorWndProc(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam) override;

    Component(WinApiElement* Parent, DWORD dwExStyle, LPCSTR nComponent, DWORD ndwStyle, bool parentWndProc, int nleft = 0, int ntop = 0, int nwidth = 200, int nheight = 100);
    ~Component();

    WinApiElement* parent;

    bool setPosition(int newX, int newY);
    bool setSize(int newWidth, int newHeight);
    bool setLocation(int newX, int newY, int newWidth, int newHeight);

    int getX();
    bool setX(int newX);
    int getY();
    bool setY(int newY);
    int getWidth();
    bool setWidth(int Width);
    int getHeight();
    bool setHeight(int Height);

    void setTransparent(bool newTransparent);
    void Repaint();
    // Components control metods
    virtual void OnResize();
    virtual void OnMouseMove(int moveX, int moveY);
    virtual void OnMouseLeftDown();
    virtual void OnMouseRightDown();
    virtual void OnPaint();
    virtual void OnMouseEnter();
    virtual void OnMouseLeave();
    virtual void OnLeftButtonHoldDown();
    // -------------------------

    void Show(bool value);

    void setBorder(bool value);

    bool Refresh();

    virtual void OnPaint(HWND handle, HDC hdc);
};

此类中的主要功能是Create,因为它设置了WndProc和UserData。

void Component::Create(WinApiElement* Parent, DWORD dwExStyle, LPCSTR nComponent, DWORD ndwStyle, bool parentWndProc, int nleft, int ntop, int nwidth, int nheight)
{
    componentNumber = Application::AddComponent();
    uindex = componentNumber;
    handle = CreateWindowEx(dwExStyle , nComponent, NULL, ndwStyle ,nleft,ntop,nwidth,nheight, Parent->handle, (HMENU) componentNumber, Application::GetInstance(), NULL);

    parent = Parent;

    wndProc = (LONG_PTR)StaticWndProc;// else wndProc = (LONG_PTR)Parent->StaticWndProc; 
    transparent = false;
    SetLastError(0);

    SetWindowLongPtr( handle, GWLP_WNDPROC, (LONG_PTR)wndProc);
    if(!(GetLastError() == 0))
    {
        MessageBox(NULL,"Nie udało się zmienić standardowej funkcji obsługi rozkazu dla kontrolki, nie wszystkie funkcje moga działać poprawnie!","Błąd przy tworzenia komponentu",MB_ICONWARNING);
    }   

    SetLastError(0);    
    SetWindowLongPtr( handle , GWLP_USERDATA, (LONG_PTR)((WinApiElement*)this) );
    if(!(GetLastError() == 0))
    {
        MessageBox(NULL,"Nie udało się zmienić wskaźnika w komponencie w funkcji setTransparent, nie wszystkie funkcje moga działać poprawnie!","Błąd przy zmienia parametru transparent komponentu",MB_ICONWARNING);
    }

    SetWindowPos(handle,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);

    x = nleft;
    y = ntop;
    width = nwidth;
    height = nheight;
    Refresh();
}

简单的Combobox课程。

#pragma once

#include <Windows.h>
#include "Component.h"
#include "WinApiElement.h"

class Combobox : public Component
{
public:
    Combobox(WinApiElement* Parent);
    void AddItem(LPCSTR item);
};

现在出现问题:当我运行此代码时,Combobox没有显示。但是当我没有设置WndProc和UserData时,每个方面都可以,但它并不能让我满意。

@ edit

所以这是我的StaticWndProc功能代码

LRESULT CALLBACK WinApiElement::StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // Recover the pointer to our class, don't forget to type cast it back

    WinApiElement* winptr = (WinApiElement*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    // Check if the pointer is NULL and call the Default WndProc

    if (winptr == NULL) 
    {

        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    } 
    else 
    {
        // Call the Message Handler for my class (MsgProc in my case)
        return winptr->InteriorWndProc(hwnd, uMsg, wParam, lParam); 
    }
}

在其中执行方法wndProc的InteriorWndproc。它看起来很奇怪,但InteriorWndProc支持标准Component的消息和方法WndProc对每个控件都不同。

LRESULT CALLBACK Component::InteriorWndProc(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_CREATE:
            break;

        case WM_SIZE:
            OnResize();     
            break;

        case WM_MOUSEMOVE:
            POINT pt;
            pt.x = GET_X_LPARAM(lParam);
            pt.y = GET_Y_LPARAM(lParam);

            OnMouseMove(pt.x,pt.y);

            if(LButtonDown) OnLeftButtonHoldDown();

            if(!mouseHover)
            {
                SetTimer(handle,TID_POLLMOUSE,MOUSE_POLL_DELAY,NULL);
                OnMouseEnter();
                mouseHover = true;
            }
            break;

        case WM_TIMER:
            if(mouseHover)
            {
                RECT rc;
                GetWindowRect(handle,&rc);
                GetCursorPos(&pt);
                if(!PtInRect(&rc,pt))
                {
                    KillTimer(handle,TID_POLLMOUSE);
                    OnMouseLeave();
                    mouseHover = false;
                    LButtonDown = false;
                    break;
                }
            }
            break;

        case WM_PAINT:
            OnPaint();
            break;

        case WM_LBUTTONDOWN:
            OnMouseLeftDown();
            if(transparent)
            {
                ((Component*)parent)->OnMouseLeftDown();
            }
            if(!LButtonDown)
            {
                OnLeftButtonHoldDown();
                LButtonDown = true;
            }
            break;

        case WM_LBUTTONUP:
            LButtonDown = false;
            break;

        case WM_RBUTTONDOWN:
            OnMouseRightDown();
            break;

        case WM_COMMAND:

            break;
    }

    WndProc(hwnd,uMsg,wParam,lParam);

    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

0 个答案:

没有答案