2016-09-04 4 views
-5

Chaque exemple de code que j'ai vu est GetDC et releaseDC encore et encore. (ou BeginPaint/EndPaint) Mais je pense que l'écran de dessin se produit très fréquemment (surtout dans le jeu), les stocker dans la mémoire est préférable puis obtenir et libérer tout le temps. J'ai donc aimé garder globalDC comme global et l'utiliser, ne le relâchez qu'à la fin du programme. Mais pourquoi les gens ne font pas comme ça? (peut-être Obtenir/Libérer DC coûte très peu?)Win32API) Pourquoi devrais-je obtenir GetDC et ReleaseDC encore et encore?

case WM_CREATE: 
    hdc = GetDC(hWnd); //hdc is declared as global HDC 
    MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1)); 
    return 0; 
case WM_PAINT: 
    MemDC = CreateCompatibleDC(hdc); 
    OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap); 
    BitBlt(hdc, 0, 0, 300, 300, MemDC, 0, 0, SRCCOPY); 
    SelectObject(MemDC, OldBitmap); 
    DeleteDC(MemDC); 
    return 0; 
+4

* "Mais pourquoi les gens ne font pas comme ça?" * - Parce que tout est faux . Vous avez donc sauvegardé l'opération bon marché 'GetDC' uniquement pour appeler le coûteux sur chaque redraw (' CreateCompatibleDC'). Et puisque vous n'appelez jamais 'BeginPaint' /' EndPaint', la région invalide n'est jamais validée, provoquant la génération de messages 'WM_PAINT' continus, même quand il n'y a rien à dessiner. Vous devez apprendre comment cela fonctionne avant d'essayer d'optimiser. – IInspectable

+0

Les gens ne le font pas comme ça parce que la documentation dit que vous ne pouvez pas. Les contrôleurs de domaine ne doivent pas être mis en cache comme ceci, à moins que vous ne preniez soin de créer votre classe de fenêtre avec les drapeaux appropriés, ce que vous ne devriez pas faire. Les contrôleurs de domaine sont conçus pour être des objets temporaires, créés uniquement lorsque cela est nécessaire et éliminés immédiatement après. Récupération d'un DC avec 'GetDC' est assez bon marché que cela a bien fonctionné sur 286 processeurs. Il est * garanti * d'être assez rapide sur le silicium que vous utilisez actuellement. –

+0

@CodyGray Wow ma curiosité juste époustouflé! Merci à tous pour votre réponse. – JokyDandy

Répondre

0

Le code que vous avez présenté ici est faux. Tout d'abord, vous devez lire un peu plus de la documentation. Voici un lien utile: Painting and Drawing. Fondamentalement, il existe deux façons de mettre à jour une fenêtre:

  • En réponse au message WM_PAINT. Utilisez les fonctions BeginPaint()/EndPaint() pour peindre la zone client correctement. Ce message est envoyé par le système lorsqu'une partie de la zone cliente est "invalidée" (en raison du redimensionnement, de la restauration à partir de l'état réduit, du déplacement d'une fenêtre qui l'obscurcissait auparavant ou de l'invalidation programmatique.) WM_PAINT est un message de priorité basse, reçu juste avant que la file d'attente des messages ne soit vide
  • Dessiner spécifiquement une partie ou la totalité de la zone cliente sans avoir de zone invalide, utilisez GetDC()/ReleaseDC() pour cela. Utile si vous voulez que les modifications soient immédiatement visibles , lorsque l'application (CPU) est occupé.

écrire du code pour traiter le message WM_PAINT est normalement presque obligatoire, tout en tirant spécifiquement et est facultative, en fonction des besoins de votre application.

Ne jamais envoyer ou publier un message WM_PAINT vous-même, au lieu d'invalider une partie ou la totalité de la zone client - l'application recevra un message WM_PAINT avant d'être inactif. Si vous voulez que la peinture se produise immédiatement, appelez UpdateWindow() - cela contourne la file d'attente de messages.

0

Une mise à jour de sécurité récente (août 2016) dans Windows 10 empêche la réutilisation des contextes de périphérique d'imprimante. Après l'impression d'un document, Windows 10 refusera d'imprimer à nouveau avec ce même DC. Il a toujours été préférable de créer un nouveau DC pour chaque document, mais maintenant il semble être une exigence dans Windows 10.