2009-10-24 4 views
0

J'écris un contrôle dont certaines de ses parties peuvent être transparentes ou semi-transparentes. Fondamentalement, ce contrôle montre une image png (avec canal alpha). La fenêtre parent du contrôle contient des graphiques. Par conséquent, pour que le contrôle png soit rendu correctement, il doit obtenir une image de ce que la fenêtre parente dessine sous elle. La boîte de dialogue Parent peut avoir un drapeau WS_CLIPCHILDREN défini, ce qui signifie que la fenêtre parente ne dessine rien sous le contrôle png et dans ce cas, le contrôle png ne fonctionnera pas correctement. Ce contrôle doit fonctionner sur Windows Mobile également, donc il ne peut pas avoir WS_EX_TRANSPARENTContrôle enfant transparent

Répondre

0

Drôle, vous devriez demander. Je viens d'écrire du code pour le faire hier. C'est dans la base de code pour Project Resistance. Regardez comment ResistorView (qui a un PNG avec transparence) interagit avec MainForm (qui a l'image d'arrière-plan).

0

Je ne fais pas C#, donc je ne pense pas que cela pourrait être utile. J'ai essayé de regarder dans votre code et je ne vois rien qui puisse résoudre mon problème même si vous accomplissez la même tâche que moi. Pour plus de détails, mon contrôle prend également en charge l'animation gif et j'ai également utilisé la même charge IImage à partir du flux que dans votre projet. D'après mon expérience, cette charge IImage de flux est un code indésirable incroyable, c'est extrêmement lent. Je n'ai aucune idée de comment cela pourrait être si lent. Chargement 32x32 gif avec 31 images prend comme 1.5secods en utilisant ce truc IImage indésirable. J'ai écrit mon propre chargeur (en utilisant une bibliothèque gif d'opensource) et sans aucune optimisation, le décodage/chargement complet des images gif prend moins de 100ms. J'utilise TouchPro2 ... Je ne peux pas imaginer à quel point ce code fonctionnerait sur un appareil bas de gamme.

Comme une alternative rapide est ici une solution à ma question:

dans le gestionnaire WM_PAINT du contrôle enfant qui dessine des images (gif ou png) Je fais ce qui suit:

d'abord, j'appelle setRedraw (faux) sur soi-même et sur la fenêtre parent. puis je cache le contrôle enfant et envoie WM_PAINT à la fenêtre parente avec HDC facultatif (comme wParam). La fenêtre parente rend tout à la bitmap hors écran (transmis via hdc à WM_PAINT) et après le retour réussi de WM_PAINT, je prends la partie pertinente du bitmap hors écran. Ensuite, j'active la fenêtre enfant et appelle SetRedraw (true) sur l'enfant et la fenêtre parent. Cette astuce fonctionne mais a évidemment quelques inconvénients (j'ai besoin de créer un énorme bitmap hors écran pour capturer toute la zone de l'écran même si j'ai besoin de 32x32 pixels au milieu de la fenêtre parent).

le code est ci-dessous:

bool pic_control::get_parent_bg(MyBitmap & bg) 
{ 
    CWindow parent = GetParent(); 
    CClientDC dc(parent); 
    bool is_visible = IsWindowVisible() && parent.IsWindowVisible(); 
    if(!is_visible){ 
     return false; 
    } 

    parent.SetRedraw(false); 
    SetRedraw(false); 

    CRect rect; 
    parent.GetClientRect(rect); 
    MyBitmap bmp; 
    bmp.create(rect.Width(), rect.Height()); 

    ShowWindow(SW_HIDE); 
    parent.SendMessage(WM_PAINT, (WPARAM)(HDC)bmp.dc()); 
    ShowWindow(SW_SHOW); 

    GetWindowRect(rect); 
    parent.ScreenToClient(rect); 
    bg.create(rect.Width(), rect.Height()); 
    bg.dc().BitBlt(0, 0, rect.Width(), rect.Height(), bmp.dc(), rect.left, rect.top, SRCCOPY); 

    IF_DEBUG SAL::saveHBITMAPToJpeg(bg.GetBitmap(), "frames/BG.jpg", 100); 

    SetRedraw(true); 
    parent.SetRedraw(true); 
    return true; 
} 
0

WS_CLIPCHILDREN est forcé dans WinCe, vous ne pouvez pas l'activer. Je ne sais pas pourquoi, peut-être que c'est fait pour des raisons de performance. D'après mon expérience ce que j'ai fait dans cette situation. 1) Si la fenêtre parent bacgkround est dynamique (par exemple une fenêtre qui contient map, qui peut être déplacée), elle est d'abord peinte sur la toile mémoire, puis sur l'écran et la toile mémoire est sauvegardée et utilisée pour peindre les transparents. Le canevas de mémoire ne contient pas de trous à la place des fenêtres enfants, il peut donc être utilisé pour d'autres fusions de pixels. L'inconvénient ici est la consommation de mémoire pour tenir la toile en mémoire.

2) Si l'arrière-plan de la fenêtre parent est statique (boîte de dialogue, menu, etc.), vous pouvez créer des enfants non-fenêtre.

class CImageButton 
{ 
public: 
bool IsPointInside(POINT pt); 
void OnPaint(HDC canvas); 
void OnClick(); 
void SetRect(RECT& rc); 
private: 
RECT m_rc; 
}; 

Votre fenêtre parent contiendra un tableau de ces objets et de rediriger WM_PAINT et clics de souris pour eux.Le désavantage est un code supplémentaire nécessaire pour être ajouté à la fenêtre parente, mais vous pouvez créer une classe de base pour toutes vos fenêtres parentes, ce qui gérera les problèmes avec les contrôles non fenêtrés.

Questions connexes