Resumo

As aplicações baseadas no Windows exibem frequentemente caixas de diálogo de entrada de dados para solicitar informações dos utilizadores. Estas caixas de diálogo podem conter vários controlos de edição e dois botões de comando (push), marcados como OK e CANCEL. Um exemplo de uma caixa de diálogo de entrada de dados é aquele que solicita informações pessoais, tais como número de segurança social, morada, número de identificação (ID), data/hora, e assim por diante, dos utilizadores. Cada um destes itens é inserido num controlo de edição. Por predefinição, a tecla TAB é utilizada numa caixa de diálogo para deslocar o foco entre os controlos de edição. No entanto, como interface de utilizador comum, também se pode utilizar a tecla ENTER (RETURN) para mover-se entre os controlos de edição (por exemplo, depois de o utilizador introduzir uma informação, pressionar o ENTER move o foco para o campo seguinte). Existem algumas formas de permitir a utilização da tecla ENTER para mover-se entre os controlos de edição. Um método é fazer uso de WM_COMMAND e as mensagens de notificação que acompanham na caixa de diálogo para controlos e botões de edição. Outro método envolve subclassificar os controlos de edição. Um terceiro envolve a utilização do App Studio e do Assistente de Classe e a criação de uma nova função de membro da caixa de diálogo.

Mais Informações

Método I: (WM_COMMAND)

Este método baseia-se no seguinte comportamento das caixas de diálogo (Gestor de diálogo) e do manuseamento de foco no Windows.Se uma caixa de diálogo ou um dos seus controlos tiver atualmente o foco de entrada, premindo a tecla ENTER faz com que o Windows envie uma mensagem de WM_COMMAND com o parâmetro idItem (wParam) definido para o ID do botão de comando predefinido. Se a caixa de diálogo não tiver um botão de comando predefinido, então o parâmetro idItem é definido para IDOK por predefinição. Quando uma aplicação recebe a mensagem WM_COMMAND com idItem definida para o ID do botão de comando predefinido, o foco permanece com o controlo que tinha o foco antes da tecla ENTER ser premida. Call GetFocus() neste momento devolve o cabo do controlo que tinha o foco antes da tecla ENTER ser pressionada. A aplicação pode verificar esta pega de controlo e determinar se pertence a algum dos controlos de edição na caixa de diálogo. Se isso acontecer, o utilizador estava a introduzir dados num dos controlos de edição e, depois de o fazer, pressionou o ENTER. Neste ponto, a aplicação pode enviar a mensagem WM_NEXTDLGCTL para a caixa de diálogo para mover o foco para o controlo seguinte. No entanto, se o foco foi com um dos botões de comando (CANCEL ou OK), então o GetFocus () devolve um manípulo de controlo de botões, altura em que se pode descartar a caixa de diálogo. O pseudo código para esta lógica assemelha-se ao seguinte no procedimento da caixa de diálogo da aplicação:

     case WM_COMMAND:     if(wParam=IDOFDEFBUTTON || IDOK) {          // User has hit the ENTER key.          hwndTest = GetFocus() ;          retVal = TesthWnd(hWndTest) ;          //Where retVal is a boolean variable that indicates whether        //the hwndTest is the handle of one of the edit controls.          if(hwndTest) {         //Focus is with an edit control, so do not close the dialog.            //Move focus to the next control in the dialog.         PostMessage(hDlg, WM_NEXTDLGCTL, 0, 0L) ;         return TRUE ;          }          else {            //Focus is with the default button, so close the dialog.            EndDialog(hDlg, TRUE) ;            return FALSE ;          }        }     break ;

Método II

Este método envolve subclasse/superclassificação do controlo de edição na caixa de diálogo. Uma vez que os controlos de edição são subclassificados ou superclassificados, toda a entrada do teclado é enviada o procedimento subclasse/superclasse do controlo de edição que tem atualmente foco de entrada, independentemente de a caixa de diálogo ter ou não um botão de comando predefinido. A aplicação pode prender a chave para baixo (ou char) mensagens, procurar a tecla ENTER e fazer o processamento em conformidade. Segue-se um procedimento de subclasse de amostra que procura a chave ENTER:

   //*-------------------------------------------------------------------   //| Title:   //|     SubClassProc   //|   //| Parameters:   //|     hWnd            - Handle to the message's destination window   //|     wMessage        - Message number of the current message   //|     wParam          - Additional info associated with the message   //|     lParam          - Additional info associated with the message   //|   //| Purpose:   //|     This is the window procedure used to subclass the edit control.   //*---------------------------------------------------------------------   long FAR PASCAL SubProc(HWND hWnd, WORD wMessage,WORD wParam,LONG                           lParam)   {       switch (wMessage)        {             case WM_GETDLGCODE:               return (DLGC_WANTALLKEYS |                       CallWindowProc(lpOldProc, hWnd, wMessage,                                      wParam, lParam));             case WM_CHAR:             //Process this message to avoid message beeps.            if ((wParam == VK_RETURN) || (wParam == VK_TAB))              return 0;               else              return (CallWindowProc(lpOldProc, hWnd,                                        wMessage, wParam, lParam));          case WM_KEYDOWN:               if ((wParam == VK_RETURN) || (wParam == VK_TAB)) {                 PostMessage (ghDlg, WM_NEXTDLGCTL, 0, 0L);                 return FALSE;               }            return (CallWindowProc(lpOldProc, hWnd, wMessage,                                      wParam, lParam));            break ;          default:               break;        } /* end switch */ 

Método 3

Este método envolve a utilização do App Studio e classWizard e a criação de uma nova função de membro da caixa de diálogo. Este método permitirá que um utilizador pressione a tecla ENTER e tenha o foco a avançar para o próximo controlo de edição. Se o foco estiver atualmente no último controlo de edição na caixa de diálogo, o foco avançará para o primeiro controlo de edição. Em primeiro lugar, utilize o App Studio para alterar o ID do botão OK da caixa de diálogo. O comportamento padrão do App Studio é dar ao botão OK o ID IDOK. O ID do botão OK deve ser alterado para outro valor, como IDC_OK. Além disso, altere as propriedades do botão OK de modo a que não seja um botão predefinido. Em seguida, use ClassWizard para criar um novo funciton membro da caixa de diálogo. Nomeie a função do novo membro algo como OnClickedOK. Esta função deve estar ligada à mensagem BN_CLICKED do controlo IDC_OK. Uma vez feito isto, escreva o corpo da função OnClickedOK. Deve colocar o código que normalmente colocaria na função OnOK na nova função OnClickedOK, incluindo a função OnOK de uma classe. Adicione o seguinte protótipo ao ficheiro do cabeçalho para a caixa de diálogo:

   protected:      virtual void OnOK();

Adicione uma função OnOK à caixa de diálogo e o código é como demonstrado abaixo:

   void CMyDialog::OnOK()   {        CWnd* pwndCtrl = GetFocus();        CWnd* pwndCtrlNext = pwndCtrl;        int ctrl_ID = pwndCtrl->GetDlgCtrlID();        switch (ctrl_ID) {            case IDC_EDIT1:                pwndCtrlNext = GetDlgItem(IDC_EDIT2);                break;            case IDC_EDIT2:                pwndCtrlNext = GetDlgItem(IDC_EDIT3);                break;            case IDC_EDIT3:                pwndCtrlNext = GetDlgItem(IDC_EDIT4);                break;            case IDC_EDIT4:                pwndCtrlNext = GetDlgItem(IDC_EDIT1);                break;            case IDOK:                CDialog::OnOK();                break;            default:                break;        }        pwndCtrlNext->SetFocus();   }

Precisa de mais ajuda?

Quer mais opções?

Explore os benefícios da subscrição, navegue em cursos de formação, saiba como proteger o seu dispositivo e muito mais.