5 关闭窗口(harib20e)

现在我们终于可以在窗口上画线玩了,不过一个重大的问题出现了:在应用程序结束之后,窗口依然还留在画面上。

这是因为系统为留在画面上的这个窗口分配了应用程序的数据段作为存放窗口图层的内存空间,当应用程序活动时没有任何问题,但当应用程序运行结束后,其数据段的内存空间就被释放出来,供操作系统及其他应用程序来使用。所以这样不行。

因此在应用程序结束之前,我们需要先关闭窗口。

■■■■■

首先还是像之前一样,编写一个API。

关闭窗口

EDX=14

EBX=窗口句柄

本次的console.c节选

  1. int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
  2. {
  3. (中略)
  4. } else if (edx == 14) {
  5. sheet_free((struct SHEET *) ebx);
  6. }
  7. return 0;
  8. }

非常简单吧。

然后我们来编写应用程序。写一个新的应用程序太麻烦了,我们就用之前的lines.c修改一下。

本次的a_nask.nas节选

  1. _api_closewin: ; void api_closewin(int win);
  2. PUSH EBX
  3. MOV EDX,14
  4. MOV EBX,[ESP+8] ; win
  5. INT 0x40
  6. POP EBX
  7. RET

本次的lines.c

  1. int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
  2. void api_initmalloc(void);
  3. char *api_malloc(int size);
  4. void api_refreshwin(int win, int x0, int y0, int x1, int y1);
  5. void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
  6. void api_closewin(int win);
  7. void api_end(void);
  8. void HariMain(void)
  9. {
  10. char *buf;
  11. int win, i;
  12. api_initmalloc();
  13. buf = api_malloc(160 * 100);
  14. win = api_openwin(buf, 160, 100, -1, "lines");
  15. for (i = 0; i < 8; i++) {
  16. api_linewin(win + 1, 8, 26, 77, i * 9 + 26, i);
  17. api_linewin(win + 1, 88, 26, i * 9 + 88, 89, i);
  18. }
  19. api_refreshwin(win, 6, 26, 154, 90);
  20. api_closewin(win); /*这里! */
  21. api_end();
  22. }

好了,大功告成,这个也挺简单的呢。

我们来“make run”试试看吧。哦哦,运行成功,窗口消失了。

5 关闭窗口(harib20e) - 图1

看,窗口消失了吧?

嗯,不过这样一来,窗口只显示了一下就瞬间消失了,我们连显示出来的内容都看不清。在程序结束之前关闭窗口固然很好,可是这样的话显示窗口就没有意义了嘛。