Outils pour utilisateurs

Outils du site


fr:data_grid

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
fr:data_grid [2012/05/16 08:42]
navy57 créée
fr:data_grid [2012/10/09 09:20] (Version actuelle)
darcybarron [Anatomie d'un contrôle personnalisé (grille de données simple)]
Ligne 2: Ligne 2:
  --- //David MacDermot 2008/09/17 19:55//  --- //David MacDermot 2008/09/17 19:55//
  
-Cet article décrit comment créer un contrôle personnalisé dans Pelles C. Le contrôle dans ce cas est une grille de données, utilisant comme composant un affichage de liste "​listview"​ et une zone d'​édition "​editbox"​ avec un certain nombre de personnalisations pour améliorer l'​apparence du contrôle.+Cet article décrit comment créer un contrôle personnalisé dans Pelles C. Le contrôle dans ce cas est une grille de données, utilisant comme composant un affichage de liste "​listview"​ et une zone d'​édition "​editbox"​ avec un certain nombre de personnalisations pour améliorer l'​apparence du contrôle. ​[[http://​termpaper.biz/​buy-paper-online.php|buy admission essay]]
  
-===== Project ​===== + 
-{{:​data_grid:​sdkdatagridview.zip|Project ​Source ​and Demo}}+===== Projet ​===== 
 +{{:​data_grid:​sdkdatagridview.zip|.zip Source ​de projet et Démo}}
  
  
Ligne 11: Ligne 12:
 ===== Introduction ===== ===== Introduction =====
  
-The Windows ​SDK provides a selection of user interface ​controls for application development that covers most of the bases when it comes to user interface ​design ​Sooner or later howeveryou run into a situation ​where you wish there was something else in the toolbox that isn’t there A search of the web reveals a number of clever ​solutions ​but most of them use MFC or another of the modern object oriented platforms and they don’t translate well into Pelles C.  More often than not you are going to have to create your own control from scratch+Le SDK de Windows fournit une sélection de contrôles d'interface ​utilisateur pour le développement d'​applications qui couvre la plupart des bases lorsqu'​il s'agit de conception d'interface ​utilisateurTôt ou tard,vous vous trouverez dans une situation ​ou vous souhaiteriez avoir certain éléments dans la boîte à outils qui n'y figure pasUne recherche sur le web révèle un certain nombre de solutions ​intelligentes,​ mais la plupart d'​entre eux utilisent des plates-formes ​MFC ou autre orientations d'​objets modernes,​qui se traduisent mal en Pelles C. Le plus souvent vous allez devoir créer votre propre contrôle à partir de zéro.La conception de votre propre contrôle ne doit pas être une affaire difficile 
-The good news is rolling your own control does not have to be a difficult proposition.+
  
-===== The windows class =====+===== La classe des fenêtres ​=====
  
-The windows class describes common properties of all windows that will be created using that class  We’ll use the Windows ​class to encapsulate the methods associated with our custom control and also to provide the public ​interface ​for our control The public ​interface ​for our control will be message ​based so there is only one public method that we create in order to register the windows class This method is called only once to register the class ​Instances of the control are created using **CreateWindow()**.+La classe décrit les propriétés communes des fenêtres de toutes les fenêtres qui seront créés à l'aide de cette classeNous allons utiliser la classe ​Windows ​pour encapsuler les méthodes associées à notre contrôle personnalisé et aussi pour fournir l'interface ​publique pour notre contrôleL'interface ​publique pour notre contrôle sera le message ​de base de sorte qu'il n'​existe qu'une seule méthode publique que nous créons dans le but d'​enregistrer la classe des fenêtresCette méthode est appelée une seule fois pour enregistrer la classeLes instances de contrôle sont créés en utilisant ​**CreateWindow()**.
  
 <code c>ATOM InitDataGridView(HINSTANCE hInstance) <code c>ATOM InitDataGridView(HINSTANCE hInstance)
Ligne 41: Ligne 42:
 }</​code> ​ }</​code> ​
  
-This method should be called in the application's entry point procedure immediately following the calls to initialize common controls.+Cette méthode doit être appelée dans la procédure de l'application de point d'​entrée,​ immédiatement après les appels vers l'​initialisation des contrôles communs.
  
 <code c>int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,​ LPSTR lpszCmdLine,​ int nCmdShow) <code c>int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,​ LPSTR lpszCmdLine,​ int nCmdShow)
Ligne 61: Ligne 62:
 </​code>​ </​code>​
  
-===== The callback procedure ​=====+===== La procédure de rappel ​=====
  
-This is where we’ll support the public ​interface ​to our control as well as handle the standard windows ​messages ​that the operating system sends to our control’s window+C'est là que nous allons fournir l'interface ​publique à notre contrôle, ainsi que gérer les messages ​standard de Windows que le système d'​exploitation envoie vers la fenêtre de notre contrôle
  
-Callback procedures can become quite lengthy and difficult to maintain in a complex control Windows ​provides a series of macros ​in **windowsx.h** ​and **comctrl.h** ​that greatly enhance ​code readability and help to break out code into manageable event driven method chunks ​These ​macros ​are referred to as message ​crackers ​and there are some tools that make implementing them fairly easy I used the [[http://​www.codeproject.com/​KB/​winsdk/​msgcrackwizard.aspx|Message Cracker Wizard]] ​to generate the macros ​and method ​prototypes ​for the standard windows ​messages, ​greatly reducing the size of the callback procedure.+Les procédures de rappel peuvent devenir très longue et difficile à maintenir dans un contrôle complexe. Windows ​fournit une série de macros ​dans ** windowsx.h ** et ** comctrl.h ** afin d'​améliorer grandement la lisibilité du code et d'​aider à sortir le code en blocs d'​événements gérables axés sur la méthodeCes macros ​sont considérés comme des crackers ​de message et il existe des outils qui rendent leur mise en œuvre assez facileJ'ai utilisé ​[[http://​www.codeproject.com/​KB/​winsdk/​msgcrackwizard.aspx|Message Cracker Wizard]] ​pour générer les macros ​et les prototypes ​de méthode pour les messages ​standard de Windowsce qui réduit considérablement la taille de la procédure de rappel.
  
-Most of the lines of code in this section ​are devoted to the control’s own custom ​messages ​and indeed mimic the property getters and setters common to C++.+La plupart des lignes de code dans cette section ​sont consacrés aux propres du contrôle des messages ​personnalisés et même imiter les acquéreurs et mutateurs de propriété communs à C++.
  
 <code c>static LRESULT CALLBACK Grid_WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) <code c>static LRESULT CALLBACK Grid_WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Ligne 113: Ligne 114:
 </​code>​ </​code>​
  
-===== The public ​interface =====+===== L'interface ​publique ​=====
  
-We’ll define the public ​interface ​in the control’s header file.+Nous allons définir l'​en-tête de l'interface ​publique dans le fichier du contrôle.
  
-Windows ​reserves a block of messages ​for custom controls beginning with the definition of  ​**WM_USER** ​so our messages ​will be **WM_USER** + some value we assign ​Messages are sent to a control via **SendMessage()** ​which gives us two parameters that we can use for passing values to the control’s callback procedure We can also obtain the callback return value from **SendMessage()**. ​ I find it helpful to define ​macros ​for each message ​as I define the messages ​themselves This serves as a way of documenting each message ​in the code of the header file during development and provides a syntactically pleasing ​interface ​for accessing the control’s properties in source ​code.+Windows ​réserve un bloc de messages ​pour les contrôles personnalisés en commençant par la définition ​**WM_USER** ​afin que nos messages ​soient ​**WM_USER**+, nous allons assignerune certaine valeur. Les messages sont envoyés à un contrôle par l'​intermédiaire ​**SendMessage()**.ce qui nous donne deux paramètres que nous pourrons utiliser pour passer des valeurs à la procédure de rappel du contrôle. On peut aussi obtenir la valeur de retour de rappel à partir de **SendMessage()** . Je trouve qu'il est utile de définir des macros ​pour chaque ​message ​que de définir les messages ​eux-mêmesCela constitue un moyen de documenter chaque ​message ​dans le code du fichier d'​en-tête au cours du développement et fournit une interface ​agréable syntaxiquement pour accéder aux propriétés du contrôle dans le code source.
  
-In addition to the message macros ​I have also defined some helper macros to make it easier to add columns and rows to our control ​Notice that these macros ​do not contain references to our custom ​messages! ​ In the control’s callback procedure any listview ​specific message is forwarded to the grid control’s ​listview ​component.+En plus des macros de message ​j'ai également défini quelques ​macros ​d'​assistance pour rendre plus facile l'​ajout de colonnes et de lignes à notre contrôleNotez que ces macros ​ne contiennent aucune références à notre messages ​personnalisésDans la procédure de rappel du contrôle toute les messages spécifiques ​listview ​sont transmis à la composante du contrôle de grille de listview.
  
 <code c>/​****************************************************************************/​ <code c>/​****************************************************************************/​
Ligne 182: Ligne 183:
  
 /​****************************************************************************/​ /​****************************************************************************/​
-// Exported function prototypes+// Prototypes de fonctions exportées
  
 BOOL InitDataGridView(HINSTANCE hInstance); BOOL InitDataGridView(HINSTANCE hInstance);
 </​code>​ </​code>​
  
-===== Keeping track of multiple ​instances =====+===== Assurer le suivi de plusieurs ​instances =====
  
-I use a struct ​to persist properties of each instance ​of the custom control.+J'​utilise une struct ​pour persister des propriétés de chaque ​instance ​du contrôle personnalisé.
  
 <code c>​typedef struct _tagINSTANCEDATA{ <code c>​typedef struct _tagINSTANCEDATA{
Ligne 209: Ligne 210:
 </​code>​ </​code>​
  
-In addition to this there are some standard ​methods that I use to manage the creation and assignment of, access to, and destruction ​of this structure.+En plus de cela, il ya certaines méthodes ​standard ​que j'​utilise pour gérer la création et l'​attribution de .access to, et la destruction ​de cette structure.
  
 <code c>static BOOL Control_GetInstanceData (HWND hControl, LPINSTANCEDATA *ppInstanceData) <code c>static BOOL Control_GetInstanceData (HWND hControl, LPINSTANCEDATA *ppInstanceData)
Ligne 238: Ligne 239:
 </​code>​ </​code>​
  
-Here I create and assign the structure ​in the WM_CREATE ​handler of the custom control+Ici, je créer et j’attribue la structure ​dans le gestionnaire ​WM_CREATE ​du contrôle personnalisé
  
 <code c> static BOOL Grid_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) <code c> static BOOL Grid_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
Ligne 249: Ligne 250:
  memset(&​inst.vsInfo,​ 0, sizeof(SCROLLINFO));​  memset(&​inst.vsInfo,​ 0, sizeof(SCROLLINFO));​
  
- // get the hInstance+ // aller à hInstance
  inst.hInstance = lpCreateStruct->​hInstance;​  inst.hInstance = lpCreateStruct->​hInstance;​
  
-    // create the ListView ​control+    // créer le contrôle ​ListView
     inst.hwndList = CreateListView(lpCreateStruct->​hInstance,​ hwnd);     inst.hwndList = CreateListView(lpCreateStruct->​hInstance,​ hwnd);
  if(NULL == inst.hwndList) return FALSE;  if(NULL == inst.hwndList) return FALSE;
  
- // default ​ListView ​Colors+ // Couleurs par défaut de la  ​ListView
  inst.fPaintByRow = TRUE;  inst.fPaintByRow = TRUE;
  inst.Alt_TxtColr = ListView_GetTextColor(inst.hwndList);​  inst.Alt_TxtColr = ListView_GetTextColor(inst.hwndList);​
  inst.Alt_BkColr = ListView_GetBkColor(inst.hwndList);​  inst.Alt_BkColr = ListView_GetBkColor(inst.hwndList);​
  
- // default ​ListView pseudoHeaders off+ // ListView pseudoHeaders off par défaut
  inst.fRowHeaders = FALSE;  inst.fRowHeaders = FALSE;
  
Ligne 267: Ligne 268:
  if(NULL == inst.hwndEditor) return FALSE;  if(NULL == inst.hwndEditor) return FALSE;
  
- // default Cell Editor Colors+ // Couleurs par défaut de la cellule d'​édition
  inst.Editor_BkColr = RGB(0,​0,​160);​  inst.Editor_BkColr = RGB(0,​0,​160);​
  inst.Editor_TxtColr = RGB(255,​255,​255);​  inst.Editor_TxtColr = RGB(255,​255,​255);​
  
- // default Cell selection behavior+ // Comportement de la sélection par défaut de la cellule
  inst.fDblClick = FALSE;  inst.fDblClick = FALSE;
  
Ligne 282: Ligne 283:
 </​code>​ </​code>​
  
-Here I set a global pointer to the struct associated with this instance ​of the control and then free the structure ​when it is no longer needed.+Ici j'ai mis un pointeur vers la structure globale associée à cette instance ​du contrôle et alors libre de la structure ​quand il n'est plus nécessaire.
  
 <code c> static VOID Grid_OnDestroy(HWND hwnd) <code c> static VOID Grid_OnDestroy(HWND hwnd)
Ligne 296: Ligne 297:
 </​code>​ </​code>​
  
-===== Points ​of interest ​===== +===== Points ​d'​intérêt ​===== 
-====Custom drawing the listview ​====+ 
 +====Dessin personnalisé d'une liste  ​====
  
-All of the customization and drawingof the grid’s components, is handled in the NM_CUSTOMDRAW ​notification of the list viewthis includes skinning the headersomething that normally one cannot dobut is possible ​because the header is subclassed For a detailed tutorial about simple customizations using this method see [[http://​www.codeproject.com/​KB/​list/​lvcustomdraw.aspx|Neat Stuff to Do in List Controls Using Custom Draw]].+Toutes les personnalisations et dessins des composants de la grillesont gérées dans la notification ​NM_CUSTOMDRAW ​de la listece qui inclut le dépouillement l'​en-têtequelque chose qui normalement ne peut pas ce fairemais il est possible ​que parce que l'​en-tête est sous-classéePour un tutoriel détaillé sur les personnalisations simples en utilisant cette méthode voir [[http://​www.codeproject.com/​KB/​list/​lvcustomdraw.aspx|Trucs sympa à faire dans la liste des contrôles à l'aide dessin personnalisé]].
  
 <code c>​LRESULT Grid_OnCustomDraw (HWND hwnd, LPNMLVCUSTOMDRAW lplvcd) <code c>​LRESULT Grid_OnCustomDraw (HWND hwnd, LPNMLVCUSTOMDRAW lplvcd)
Ligne 410: Ligne 412:
 </​code>​ </​code>​
  
-====Getting the column count ====+====Obtenir le nombre de colonnes ​====
  
-The listview ​has method for getting the item count (row countbut does not provide a method for getting column count It is therefore necessary to provide an indirect ​way of determining column count One method would be to get an item count from the listview’s header but this does not work if the header is not visible ​yet The following is a method that works under any circumstances.+La listview a une méthode pour obtenir le nombre d'​éléments ​(nombre de lignes), mais ne fournit pas une méthode pour obtenir le nombre de colonnesIl est donc nécessaire de prévoir un moyen indirect ​pour déterminer le nombre de colonnesUne méthode serait d'​obtenir un nombre d'​éléments de tête de la listview, mais cela ne fonctionne pas si l'​en-tête n'est pas encore ​visible. ​Ce qui suit est une méthode qui fonctionne en toutes circonstances.
  
 <code c>static INT ListView_GetColumnCount(HWND hwnd) <code c>static INT ListView_GetColumnCount(HWND hwnd)
Ligne 441: Ligne 443:
 </​code>​ </​code>​
  
-====Positioning the editor on resize ​====+====Positionnement de l'​éditeur sur redimensionnement ​====
  
-Resizing a column is fairly straight forward But what happens to the edit control that I am positioning over the grid during a resize It must resize and position accordingly This is hard to do real time but with some smoke and mirrors I was able to make it look like that is just what is happening.+Le redimensionnement d'une colonne est assez simpleMais ce qui se passe au contrôle d'​édition que je suis le positionnement sur ​​la grille au cours d'une de redimensionnementIl faut redimensionner et positionner en conséquenceC'est difficile à faire en temps réel mais avec un peu de fumée et de miroirs, j'ai pu lui donner l'air comme ça, c'est juste ce qui se passe.
  
-The listview's header posts an HDN_ITEMCHANGING ​notification ​that signals ​resize has begun I hide the edit control when this happens but the underlying subitem is painted the same colors as the edit control so it looks like the edit control is stretching real-time All I need to do when the resize is complete is reposition the edit control and show it again ​Unfortunately there is no direct ​way to determine that a resize is complete.+Les messages d'en-tête de ListView une notification ​HDN_ITEMCHANGING qui signale un redimensionnement ​commencéJe cache le contrôle d'​édition lorsque cela se produit, mais le sous-menu sous-jacente est peint de la même couleur que le contrôle d'​édition de sorte qu'il ressemble le contrôle d'​édition est l'​étirement en temps réelTout ce que je besoin de faire lorsque le redimensionnement est terminée sont de repositionner le contrôle d'​édition et de le montrer encoreMalheureusement,​ il n'​existe aucun moyen direct ​pour déterminer si un redimensionnement est terminée
  
-I must confess that this one had me stumped for while I played with the list view and observed closely what was happening during a resize.+Je dois avouer que celui-ci m'laissé bouche bée pendant un certain tempsJ'ai joué avec l'​affichage de la liste et observer de près ce qui se passait au cours d'une de redimensionnement.
  
   * Mouse down on header   * Mouse down on header
Ligne 505: Ligne 507:
 </​code>​ </​code>​
  
-====Scrolling====+====Défilement====
  
-Getting the scrolling to work right in this control was a challenge I would resize the grid columns so that the horizontal scrollbar appearedscroll overthen resize the columns back to the initial size This caused the scrollbar to disappear leaving the view shifted and some of the control not visible. +Obtenir le fonctionnement du contrôle du défilement en plein écrand fut un défiJe voudrais redimensionner les colonnes de la grille de sorte que la barre de défilement horizontale apparaîtfaires défiler l'​écranpuis redimensionner les colonnes pour retourner à la taille initialeCela a provoqué la disparition de la barre de défilement en laissant le point de vue décalé et une partie du contrôle n'est plus visible. 
-The solution ​was to persist the vertical and horizontal scroll info in the control so that it wasn't lost when the bars vanished In the case of horizontal ​scrollingthe control pans to the origin if the size of the listview reduces to fit within the parent window+La solution ​est de conserver l'information verticale et horizontale de défilement dans le contrôle de sorte qu'il n'a pas été perdu lorsque les barres disparuDans le cas de défilement ​horizontal, ​le contrôle casseroles à l'​origine,​ si la taille de la liste réduit pour tenir dans la fenêtre apparentés
-Vertical scrolling units reflect row height and horizontal units are set by the width of the first visible ​column I find that this gives the control the smoothest scrolling behavior while avoiding widowed or orphaned rowsEspecially when navigating the control from the keyboard.+Unités de défilement verticales reflètent la hauteur des lignes et des unités horizontales qui sont fixées par la largeur de la première colonne ​visible. ​Je trouve que cela donne le contrôle du comportement plus doux de défilement tout en évitant les lignes veuves ou orphelinsSurtout lorsque vous naviguez dans le contrôle à partir du clavier.
  
-Horizontal scrolling:+Le défilement horizontale:
  
 <code c>void Grid_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos) <code c>void Grid_OnHScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos)
Ligne 573: Ligne 575:
 </​code>​ </​code>​
  
-Vertical scrolling:+Le défilement vertical:
  
 <code c>static VOID Grid_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, INT pos) <code c>static VOID Grid_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, INT pos)
Ligne 640: Ligne 642:
 </​code>​ </​code>​
  
-Calling the scroll events from the ListView_KeyProc ​so the edit box stays in view+Appel des événements de défilement de la ListView_KeyProc ​de sorte que la zone d'​édition reste en vue
  
 <code c>static LRESULT CALLBACK ListView_KeyProc (HWND hList, UINT msg, WPARAM wParam, LPARAM lParam) <code c>static LRESULT CALLBACK ListView_KeyProc (HWND hList, UINT msg, WPARAM wParam, LPARAM lParam)
 { {
- // NoteInstance data is attached to ListView's parent+ // RemarqueLes données d'instance sont attachées à une ListView aparentée
  static RECT rc, rcParent;  static RECT rc, rcParent;
  static char buf[2048];  static char buf[2048];
fr/data_grid.1337150540.txt.gz · Dernière modification: 2012/05/16 08:42 par navy57