tkMacWinMenu.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tkMacWinMenu.c --
  3.  *
  4.  * This module implements the common elements of the Mac and Windows
  5.  * specific features of menus. This file is not used for UNIX.
  6.  *
  7.  * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * RCS: @(#) $Id: tkMacWinMenu.c,v 1.3 1999/04/16 01:51:19 stanton Exp $
  13.  */
  14. #include "tkMenu.h"
  15. typedef struct ThreadSpecificData {
  16.     int postCommandGeneration;
  17. } ThreadSpecificData;
  18. static Tcl_ThreadDataKey dataKey;
  19. static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
  20. /*
  21.  *----------------------------------------------------------------------
  22.  *
  23.  * PreprocessMenu --
  24.  *
  25.  * The guts of the preprocessing. Recursive.
  26.  *
  27.  * Results:
  28.  * The return value is a standard Tcl result (errors can occur
  29.  * while the postcommands are being processed).
  30.  *
  31.  * Side effects:
  32.  * Since commands can get executed while this routine is being executed,
  33.  * the entire world can change.
  34.  *
  35.  *----------------------------------------------------------------------
  36.  */
  37. static int
  38. PreprocessMenu(menuPtr)
  39.     TkMenu *menuPtr;
  40. {
  41.     int index, result, finished;
  42.     TkMenu *cascadeMenuPtr;
  43.     ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
  44.             Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
  45.    
  46.     Tcl_Preserve((ClientData) menuPtr);
  47.     
  48.     /*
  49.      * First, let's process the post command on ourselves. If this command
  50.      * destroys this menu, or if there was an error, we are done.
  51.      */
  52.      
  53.     result = TkPostCommand(menuPtr);
  54.     if ((result != TCL_OK) || (menuPtr->tkwin == NULL)) {
  55.      goto done;
  56.     }
  57.     
  58.     /*
  59.      * Now, we go through structure and process all of the commands.
  60.      * Since the structure is changing, we stop after we do one command,
  61.      * and start over. When we get through without doing any, we are done.
  62.      */
  63.     
  64.     
  65.     do {
  66.      finished = 1;
  67.         for (index = 0; index < menuPtr->numEntries; index++) {
  68.             if ((menuPtr->entries[index]->type == CASCADE_ENTRY)
  69.                  && (menuPtr->entries[index]->namePtr != NULL)) {
  70.              if ((menuPtr->entries[index]->childMenuRefPtr != NULL)
  71.              && (menuPtr->entries[index]->childMenuRefPtr->menuPtr
  72.              != NULL)) {
  73.                  cascadeMenuPtr =
  74.                       menuPtr->entries[index]->childMenuRefPtr->menuPtr;
  75.                  if (cascadeMenuPtr->postCommandGeneration != 
  76.                       tsdPtr->postCommandGeneration) {
  77.                   cascadeMenuPtr->postCommandGeneration = 
  78.                   tsdPtr->postCommandGeneration;
  79.                      result = PreprocessMenu(cascadeMenuPtr);
  80.                      if (result != TCL_OK) {
  81.                          goto done;
  82.                      }
  83.                      finished = 0;
  84.                      break;
  85.                  }
  86.              }
  87.             }
  88.         }
  89.     } while (!finished);
  90.     
  91.     done:
  92.     Tcl_Release((ClientData)menuPtr);
  93.     return result;
  94. }
  95. /*
  96.  *----------------------------------------------------------------------
  97.  *
  98.  * TkPreprocessMenu --
  99.  *
  100.  * On the Mac and on Windows, all of the postcommand processing has
  101.  * to be done on the entire tree underneath the main window to be
  102.  * posted. This means that we have to traverse the menu tree and
  103.  * issue the postcommands for all of the menus that have cascades
  104.  * attached. Since the postcommands can change the menu structure while
  105.  * we are traversing, we have to be extremely careful. Basically, the
  106.  * idea is to traverse the structure until we succesfully process
  107.  * one postcommand. Then we start over, and do it again until
  108.  * we traverse the whole structure without processing any postcommands.
  109.  *
  110.  * We are also going to set up the cascade back pointers in here
  111.  * since we have to traverse the entire structure underneath the menu
  112.  * anyway, We can clear the postcommand marks while we do that.
  113.  *
  114.  * Results:
  115.  * The return value is a standard Tcl result (errors can occur
  116.  * while the postcommands are being processed).
  117.  *
  118.  * Side effects:
  119.  * Since commands can get executed while this routine is being executed,
  120.  * the entire world can change.
  121.  *
  122.  *----------------------------------------------------------------------
  123.  */
  124. int
  125. TkPreprocessMenu(menuPtr)
  126.     TkMenu *menuPtr;
  127. {
  128.     ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
  129.             Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
  130.     tsdPtr->postCommandGeneration++;
  131.     menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
  132.     return PreprocessMenu(menuPtr);
  133. }