Step to UEFI (29) ----- ShellPrintEx

之前使用TC的时候,有一个控制光标的函数 GotoXY(int,int) 【参考1 参考2】 可以很方便的控制光标在屏幕指定的位置写字符。我在CLIB中找了一大圈也没有踪影,后来查了一下 C99 标准【参考 3】,这个并非标准函数,所以也没有实现。

翻阅代码发现 Shell下面也有一个类似的函数 ShellPrintEx。在 \ShellPkg\Include\Library\ShellLib.h 申明如下:

/**
  Print at a specific location on the screen.

  This function will move the cursor to a given screen location and print the specified string.

  If -1 is specified for either the Row or Col the current screen location for BOTH
  will be used.

  If either Row or Col is out of range for the current console, then ASSERT.
  If Format is NULL, then ASSERT.

  In addition to the standard %-based flags as supported by UefiLib Print() this supports
  the following additional flags:
    %N       -   Set output attribute to normal
    %H       -   Set output attribute to highlight
    %E       -   Set output attribute to error
    %B       -   Set output attribute to blue color
    %V       -   Set output attribute to green color

  Note: The background color is controlled by the shell command cls.

  @param[in] Col        The column to print at.
  @param[in] Row        The row to print at.
  @param[in] Format     The format string.
  @param[in] ...        The variable argument list.

  @return EFI_SUCCESS           The printing was successful.
  @return EFI_DEVICE_ERROR      The console device reported an error.
**/
EFI_STATUS
EFIAPI
ShellPrintEx(
  IN INT32                Col OPTIONAL,
  IN INT32                Row OPTIONAL,
  IN CONST CHAR16         *Format,
  ...
  );

 

从上面可以看出,我们可以用这个函数来控制写入的位置。同时他还扩展了几个 Format.

写个程序实验一下

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>

#include  <stdio.h>
#include  <stdlib.h>
#include  <wchar.h>

#include <Protocol/EfiShell.h>
#include <Library/ShellLib.h>

extern EFI_BOOT_SERVICES             *gBS;
extern EFI_SYSTEM_TABLE			 	 *gST;
extern EFI_RUNTIME_SERVICES 		 *gRT;

int
EFIAPI
main (
  IN int Argc,
  IN char **Argv
  )
{
  
  //%H       -   Set output attribute to highlight.	
	ShellPrintEx(4,4,L"%H%S",L"LAB-Z [highlight]");
  //  %B       -   Set output attribute to blue color.	
	ShellPrintEx(6,6,L"%B%S",L"LAB-Z [blue color]");  
  //  %V       -   Set output attribute to green color.
	ShellPrintEx(8,8,L"%V%S",L"LAB-Z [green color]");  
  //  %N       -   Set output attribute to normal.
	ShellPrintEx(10,10,L"%N%S",L"LAB-Z [normal]");    
  //  %E       -   Set output attribute to error.	
	ShellPrintEx(12,12,L"%E%S",L"LAB-Z [error]");     
	
  return EFI_SUCCESS;
}

 

运行结果

29

需要特别注意的是:Error 是黄色,HightLight 是白色........

看一下具体的实现代码,在 \ShellPkg\Library\UefiShellLib\UefiShellLib.c

EFI_STATUS
EFIAPI
ShellPrintEx(
  IN INT32                Col OPTIONAL,
  IN INT32                Row OPTIONAL,
  IN CONST CHAR16         *Format,
  ...
  )
{
  VA_LIST           Marker;
  EFI_STATUS        RetVal;
  if (Format == NULL) {
    return (EFI_INVALID_PARAMETER);
  }
  VA_START (Marker, Format);
  RetVal = InternalShellPrintWorker(Col, Row, Format, Marker);
  VA_END(Marker);
  return(RetVal);
}

 

调用的 InternalShellPrintWorker 也在同一个文件中

EFI_STATUS
EFIAPI
InternalShellPrintWorker(
  IN INT32                Col OPTIONAL,
  IN INT32                Row OPTIONAL,
  IN CONST CHAR16         *Format,
  IN VA_LIST              Marker
  )

 

其中控制写入位置的是

gST->ConOut->SetCursorPosition(gST->ConOut, gST->ConOut->Mode->CursorColumn - 1, gST->ConOut->Mode->CursorRow);

 

而控制写入颜色的是

        switch (*(ResumeLocation+1)) {
          case (L'N'):
            gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute);
            break;
          case (L'E'):
            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'H'):
            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'B'):
            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'V'):
            gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          default:

 

可以看出来,Error 是黄色,HightLight 是白色........

完整代码下载

PrintEx

参考:

1.http://zhidao.baidu.com/link?url=gKNVf5BWdsVs8-NfWFmp_lbGXQNUAa5UISVTGyMusQgHQDedSwWA6ZydJIwRsEuMgd05OHN-4qR_iDNxSUkTb_

gotoxy(int x, int y);
包含头文件为:
#include

2.http://zhidao.baidu.com/link?url=knYo-KswVT4e3IOWvZc54LXR6Vh_hcfLBA6sLLKOMQImC4KN6pPoeF4pqg4QKO5cQk4PRe4FPydcBq5ZuVDprK

包含在conio.h TC2.0中应该是这个文件引入的

3.http://blog.csdn.net/zhenyongyuan123/article/details/5810253 C99标准库函数

发表评论

电子邮件地址不会被公开。 必填项已用*标注