Amiga C

22. Bölüm

Cenker Özkurt

Hepinize iyi günler! Bu ayki yazımızda, diğer sayfalarda görmüş olduğunuz gibi, uzun bir (diğerlerine göre) örnek C programıyla karşı karşıyayız. Programımız, geçen sayıda vermiş olduğum örneklerin yeni bir versiyonu. Hatırlayacağınız gibi bu örnekler, bir menü oluşturarak disketteki programlarımızı kullanmamızı sağlıyordu. Bu ay da, benzer şekilde çalışan bir örnek geliştirmeyi uygun gördüm. Fakat yeni örneğimizin aynı zamanda da bazı yeni özellikleri bulunuyor.

Programımız karışık görülebilir. Fakat sakın siz de buna aldanıp yazmaktan veya incelemekten vazgeçmeyin. Çünkü böyle programları yazabilmeniz için, öncelikle yazılanları anlayabilmeniz gerekiyor. Programı yazarken elimden geldiğince alt rutinlere bölmeye çalıştım. Böylece her rutini siz de kendi programlarınızda kullanabilir ve daha rahat anlayabilirsiniz.

Yeni bir programı denerken, kesinlikle ilk bakışta satır satır incelemeyin. Listeye bakarken, rutinleri bloklar halinde görmeye ve ayırmaya çalışın. Daha sonra her bloğun ne ise yaradığını öğrenin. Böyle incelediğiniz zaman satırlar karışık gelmez ve programı anlamanız daha kolay olur.

Programda ilk olarak incelenmesi gereken blok, 'main()' bloğudur. Blok içerisinde yapılanlara dikkat edin. Daha sonra kullanılan değişkenlerin tipini, local veya global olduğunu ve ne amaçla kullanıldığını öğrenin. Altrutinleri bulun ve hangi parametrelerle kullanıldığını görün. Bundan sonra programı satır seviyesinde inceleyebilirsiniz.

Bu kadar tavsiyeden sonra, şimdi programımızın kullanılmasına bir göz atalım. Programımız compile edilip çalıştırıldıktan sonra, bir parametre istemektedir. Bu parametre, disketteki programların listesini içeren bir dosyadır. Bu dosyada, menü ismi, programın menüdeki ve disketteki ismi bir kurala göre herhangi bir text editör (en iyisi CED) ile yazılır. Programımız bu dosyadaki listeyi hafızasındaki değişkenlere atayarak saklar. Daha sonra bu liste kullanıcının seçebilmesi için ekrana sıralanır ve mouse ile kontrol edilerek seçilir. Seçilen program disketten yüklenerek çalıştırılır ve bu arada bizim programımız da kendini hafızadan siler. Programımızın yapmış olduğu iş, kısaca bu kadar. Ben bu programı yazarken, daha önce görmüş olduğum 'Selector" adındaki bir utility programından esinlendim. Bu örneği hazırlama nedenlerimin başında, sizlerin de benzer şekilde utility programları yazabileceğinizi göstermektir.

Şimdi programımızın listesine bir göz alalım. Bu arada programımızın adını 'MenuDesign' olarak belirledim. İsterseniz siz de yeni isimler koyabilirsiniz. Ne de olsa programımız bir Public Domain !...

/*-----------------------------------------*/
/* Programming and Coding by Cenker OZKURT */ 
/*-----------------------------------------*/
/*-------------------*/
/* include Dosyalari */
/*-------------------*/
#include <exec/types.h> 
#include <exec/memory.h>
#include <graphics/gfxbase.h> 
#include <intuition/intuitionbase.h> 
#include <libraries/dos.h>

/*---------------------------*/
/* Library yapi degiskenleri */ 
/*---------------------------*/
struct IntuitionBase *IntuitionBase; 
struct GfxBase *GfxBase; 
struct DosBase *DosBase;

struct RastPort *rp; 
struct Window *window;

/*-----------------------------------------------------*/
/* Program icerisinde kullandigimiz Global degiskenler */ 
/*-----------------------------------------------------*/
char title[80];
char view[30][20];
char disk[30]|30];
char *name[]={ " ",0 };
char *list;
int no=0;
int fin;

/*-----------------------*/
/* Ana program satirlari */
/*-----------------------*/
main(argc,argv)
int argc;
char *argv[];
{
int a; /* local degisken */
if(argc==1) /* menu listesi kontrol ediliyor */
   printf("Usage : menudesign [list]\n ");
   return(1);
}
/*----------------------*/
/* library'ler aciliyor */ 
/*----------------------*/
IntuitionBase=OpenLibrary("intuition.library",0); 
GfxBase=OpenLibrary("graphics.library",0); 
DosBase=OpenLibrary("dos.library",0);

/*----------------------------------------*/
/* window ve rp degiskenleri belirleniyor */ 
/* bu degiskenler belirlenmeden           */
/* window'u kullanmamiz mümkün değil      */ 
/*----------------------------------------*/
window=IntuitionBase->ActiveWindow; 
rp=window->RPort;

SetDrMd(rp,JAM1);

/*--------------------------------------------*/
/* Bu satirlardan itibaren kendi hazirladigim */ 
/* rutinler cagriliyor                        */
/*--------------------------------------------*/
clear();       /* degiskenleri temizler */
load(argv[1]); /* menu liste dosyasini disketten yukler */
scr_clear();   /* window'u siler. -ls32 kutuphanesinde bulunur */
draw_box():    /* window'a kutulari cizer */
search();      /* listedeki isimleri degiskenlere tasir */
menudesign();  /* programin ismini ekrana yazar */
flood():       /* programlarin isimlerini kutulara yazar */
a=mouse();     /* mouse ile program secimini bekler */
if(a==0) {     /* eger secilmezse cikar */
    quit();    /* program cikisi */
    scr_clear();
    exit(0);
}

quit();
scr_clear();
printf("Loading %s...\n",view[a]);
strcpy(name[0],disk[a]); /* name yuklenecek olan ismi saklar */
execv(name[0],name);     /* diskten yukleyerek calistirir */
}

/*--------------*/
/* Cikis rutini */
/*--------------*/
quit()
{
if(list)FreeMem(list,1000);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
CloseLibrary(DosBase);
}

/*----------------*/
/* programin ismi */
/*----------------*/
menudesign()
{
char a[50];

strcpy(a,"MenuDesign (c) 1992 Programming by Cenker OZKURT");
print(320-4*(strlen(a)),192,a,strlen(a)); 
print(320-4*(strlen(title)),22,title,strlen(title));
}

/*--------------------------*/
/* degiskenler temizleniyor */ 
/*--------------------------*/
clear()
{
register int i;

for(i=0;i<30;i++) {
strcpy(view[i],"	");
	strcpy(disk[i],"	");
}
}

/*----------------------------*/
/* program isimleri yaziliyor */
/*----------------------------*/
flood()
{
register int x,y,i;

x=0; y=0;
for(i=1;i<=no;i++) {
	print(73+x*170,34+y*16,view[i],strlen(view[i]));
	y++; if(y==10) { y=0; x++; }
}
}

/*-----------------------------------------------------------*/
/* yuklenen dosyadan isimler araniyor, degiskenlere ataniyor */
/*-----------------------------------------------------------*/
search()
{
int a;
register int i,j,k;

for(i=0;i<=fin;i++) {
     a=strncmp(list+i,"menu=",5); 
     if(a==0) {
	 i+=5;
	 j=i;
	 while(*(list+i)!=10)i++;
	 for(k=0;k<i-j;k++) title[k] =(char)*(list+j+k);
	 title[k]='0';
     }
a=strncmp(list+i,"-",1);
     if(a==0) {
	 no++;
i++; j=i;
while(*(list+i)!='+')i++;
	 for(k=0;k<i-j;k++) view[no][k]=(char)*(list+j+k);
	 view[no][k]='0';
	 j=i+1;
	 while(*(list+i)!=10)i++;
	 for(k=0;k<i-j;k++) disk[no][k]=(char)*(list+j+k);
	 disk[no][k]='0';
     }
}

}

/*-----------------------*/
/* window'a yazma rutini */
/*-----------------------*/
print(x,y,a,len)
int x,y; 
char a[];
int len;
{
SetAPen(rp,2);
Move(rp,x,y);
Text(rp,a,len);
SetAPen(rp,1);
Move(rp,x-1,y-1);
Text(rp,a,len);
}

/*------------------------------------------------------*/
/* bir hafıza ayırarak, disketten listeyi buraya yükler */
/*------------------------------------------------------*/
load(a)
char [a];
{
struct FileHandle *file;
file=Open(a,MODE_OLDFILE); 
if(file==NULL) {
      printf("%s dosyası bulunamadı..!\n",a);
      quit();
      exit(1);
}
list=AllocMem(1000,MEMF_CHIP|MEMF_CLEAR)İ; 
if(list==NULL) {
      printf("Hafıza yetersiz..!\n");
      quit();
      exit(1); 
} 
fin=Read(file,list,1000);

Close(file); 
return(0);
}

/*----------------------------*/
/* window'a kutular ciziliyor */ 
/*----------------------------*/
draw_box()
{
register int x,y;

for(x=0;x<3;x++) {
 for(y=0;y<10;y++) {
   box(70+x*170,25+y*16,1);
 }
}
}

/*-------------------*/
/* kutu çizme rutini */ 
/*-------------------*/
box(x,y,c)
int c;
register int x,y;
{
SetAPen(rp,c);
Move(rp,x,y);
Draw(rp,x+160,y);
Draw(rp,x+160,y+11);
Draw(rp,x,y+11);
Draw(rp,x,y);
}

/*-------------------------------------*/
/* mouse ile program secimi bekleniyor */ 
/*-------------------------------------*/
mouse()
{
int ret;
int q,w,p=0;
int a,b,c,d;
register int x,y;
register int i,j;
UBYTE *m=0xbfe001;

 while(1) {
  x=window->GZZMouseX; 
  y=window->GZZMouseY+10; 
  for(i=0;i<3;i++) {
     for(j=0;j<10;j++) { 
	a=70+i*170; 
	b=25+j*16; 
	c=a+160;
	d=b+11;
	if(x>a&&x<c&&y>b&&y<d&&(q!=a||w!=b)) { 
	    if(p==1)box(q,w,1); else p=1; 
	    box(a,b,2); q=a; w=b;
	}
	if(!(x>70&&x<570&&y>25&&y<185)) { 
	    if(p=1) { box(q,w,1); q=0; w=0; p=0; }
	}
	if(p==0&&!(*m&64)) return(0);
	ret=i*10+j+1
     if(ret<=no&&x>a&&x<c&&y>b&&y<d&&y!(*m&64))
	return(ret);
	}
     }
 }
}
   

Programımızın daha anlaşılır olması için /* */ satırları içerisinde açıklamaları da yanlarına yazdım. Böylece hangi rutin ne işe yarar anlamak daha kolay olacaktır. Bu arada disketteki listeyi hangi kurala göre vermemiz gerektiğini bir örnekle açıklayayım: Listemiz, aşağıda olduğu gibi girilmelidir.

menu=Ceko Utility
-XcopyV6.3+xcopyv6.3
-XoperV1.3+xoperv1.3
-TurboImploderV4.0+TurboImploder4.0
-QBToolsV1.3+qbtools1.3
-Sentific Calculator+scal
-Programm Calculator+pcal
-PowerWindows+powerwindows
-PowerPackerV4.0a+powerpacker4.0a
-MultiRipperV2.0a+multiripperv2.0a
-LHarc+lharc
-FixDiskV1.2+fixdisk1.2
-DiskMasterV1.4+dm1.4
-DiskMonPro+diskmonpro
-DiskCraft+diskcraft
-Amas+amas
-Ced+ced

Böyle ayrı bir dosyada listenin girilmesinin en büyük faydası, sizin de tahmin ettiğiniz gibi yeni liste girerken her seferinde C program listesini değiştirmemiz gerekmez. Yalnızca bu dosyadaki bilgileri yeniden düzenleyip, disketteki ismiyle çağırmamız yeterli olmaktadır.

Yukarıdaki listemizin ismi 'menulist' olsun. Bu listeyi df0: içerisindeki 's' directory'sine attığımızı farzedelim. Bu durumda programı çalıştırmak için:

menudesign df0:s/menulist
yazmamız gerekmektedir. Dosyanın bulunduğu alt directory ismini ve dosya ismini doğru yazmayı unutmayın.

Bu arada yukarıdaki listeyi bir inceleyelim. Listede görüldüğü gibi çeşitli utility isimleri girilmiş. Fakat burada '-' den ve '+' dan sonra gelen isimler farklı. Bunun sebebi: '-' den sonra gelen isimlerin ekrandaki, '+' dan sonra gelen isimlerin ise disketteki isimleri belirtmesinden doğuyor. Bu nedenle özellikle '+' dan sonra gelen isimlerin, diskette aynı isim altında bulunması şart. En baştaki 'menu=' ifadesinden sonraki isim ise listenin menü başlığını oluşturuyor.

Evet, sonuç olarak liste girilmesi için başka bir kurala gere yok. Ancak şunu da belirtmem gerekir ki, kural dışı bir yazılım sonucu olacaklardan sorumlu değilim!.

Programın hazırlanması da aşağıda olduğu gibidir;

Compile işlemi kısaca: CC +L -s menudesign.c 
Link işlemi ise : LN menudesign.o -ls32 -lc32
Bu ayki yazımızın da sonuna gelmiş bulunuyoruz. Programımızın tam açıklamasını yerimiz kalmadığı için gelecek ay yayınlayacağım. Şimdilik hepinize bol 'Bug'sız günler dilerim!...