home *** CD-ROM | disk | FTP | other *** search
- /* bookwin.cpp: Spellbook control program
-
- Copyright (C) 1993, 1994 John-Marc Chandonia
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "spl.hpp"
- #include "general.hpp"
- #include "spldlg.h"
- #include "bookwin.hpp"
- #include "splwin.hpp"
- #include "spldlgs.hpp"
- #include "ea.hpp"
-
- // stuff defined in the main program
- extern HAB hab;
- extern HINI hini;
- extern int windows;
- extern spellbook *masterlist;
- extern HPOINTER dragicon;
- extern HEV sem_object_started;
- extern HWND hwndhelp;
- extern char quick_master_name[256];
- extern BYTE xfer_buffer[10240];
-
- bookwindow *first=NULL; /* pointer to first spell window;
- must be most recently created one */
-
-
- // some common initialization for bookwindows; called by constructors
- void bookwindow::init(char *bookname) {
- // create object thread, while initializing other stuff
- tidobject = _beginthread(threadmain, NULL, 18000, this);
-
- ULONG flFlags = FCF_TITLEBAR |
- FCF_SIZEBORDER|
- FCF_MINMAX|
- FCF_SYSMENU|
- FCF_MENU|
- FCF_TASKLIST|
- FCF_ACCELTABLE;
-
- // add new window as the first one
- next=first;
- if (first!=NULL) first->prev=this;
- first=this;
- prev=NULL;
- saved=true;
- busy=false;
- readonly=false;
- hwndcnr=NULL;
- hwnd=NULL;
- hwndobject=NULL;
- sb = new spellbook;
- if (bookname) sb->name = strdup(bookname);
- fontname=NULL;
-
- // create the window -- requires first to point to this window!
- hwndframe = WinCreateStdWindow(
- HWND_DESKTOP,
- WS_VISIBLE,
- &flFlags,
- (PSZ)spbclass,
- (PSZ)bookname,
- WS_VISIBLE,
- 0,
- BOOKMENU,
- NULL);
-
- // get help for this frame
- if (hwndhelp)
- WinAssociateHelpInstance(hwndhelp,hwndframe);
- }
-
- // default constructor for a window not doing anything
- bookwindow::bookwindow(char *bookname) {
- filename=NULL;
- master_list_win = false;
- init(bookname);
- }
-
- // create bookwindow from a file name, or master list
- bookwindow::bookwindow(char *fname, boolean is_master) {
- ULONG count_sem;
-
- /*
- if (masterlist)
- sprintf((char *)xfer_buffer,"%s",masterlist->name);
- else sprintf((char *)xfer_buffer,"None");
-
- WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)xfer_buffer,
- (PSZ)"master name:",
- 102,
- MB_OK);
- */
-
- // clear the semaphore; will be posted when object ready.
- DosResetEventSem(sem_object_started, &count_sem);
-
- if (fname) filename = strdup(fname);
- else filename=NULL;
-
- master_list_win = is_master;
-
- init(NULL);
-
- // make the window busy.
- this->disable();
-
- // wait for object window to be ready.
- DosWaitEventSem(sem_object_started, SEM_INDEFINITE_WAIT);
-
- if (is_master) {
- WinPostMsg(hwndobject,
- WM_USER_SHOW_MASTER,
- 0,0);
- readonly=true;
- }
- else {
- WinPostMsg(hwndobject,
- WM_USER_LOAD,
- 0,0);
- }
- }
-
- bookwindow::~bookwindow() {
- // kill off object window
- WinPostMsg(hwndobject,WM_QUIT,0,0);
- // and wait for object thread to finish
- DosWaitThread(&tidobject,DCWW_WAIT);
-
- // remove from display
- WinDestroyWindow(hwndframe);
-
- // remove from linked list
- if (this==first) first=next;
- if (next!=NULL) next->prev=prev;
- if (prev!=NULL) prev->next=next;
-
- delete sb; // but not the spells inside!
-
- // delete this last, since used during WM_DESTROY
- if (filename) delete filename;
- if (fontname) delete fontname;
- }
-
- // make window busy
- void bookwindow::disable() {
- busy=true;
- WinEnableWindow(hwnd,FALSE);
- WinEnableWindow(hwndcnr,FALSE);
- }
-
- // re-enable window
- void bookwindow::enable() {
- busy=false;
- WinEnableWindow(hwnd,TRUE);
- WinEnableWindow(hwndcnr,TRUE);
- }
-
- // save spellbook as list of spells.
- boolean bookwindow::save_book(boolean just_titles) {
- FILEDLG fd;
-
- // clear all fields to zero before proceeding
- memset(&fd,0,sizeof(FILEDLG));
-
- // set up file dialog
- fd.cbSize=sizeof(FILEDLG);
- fd.fl=FDS_CENTER|FDS_SAVEAS_DIALOG;
- if (just_titles)
- fd.pszTitle=(PSZ)"Save spellbook to file:";
- else
- fd.pszTitle=(PSZ)"Save spellbook to file (with full descriptions):";
- if (filename)
- strcpy(fd.szFullFile,filename);
- else
- strcpy(fd.szFullFile,"*.sbk");
-
- if (!WinFileDlg(HWND_DESKTOP,
- hwnd,
- &fd)) return(false);
-
- if (fd.lReturn==DID_OK) {
- if (filename) delete filename;
- filename=strdup(fd.szFullFile);
- // send message in order to wait for it to finish.
- WinSendMsg(hwndobject,
- WM_USER_SAVE,
- (MPARAM)just_titles,0);
- return(true);
- }
- else return(false);
- }
-
-
- // load a new spellbook from a file
- boolean load_book() {
- FILEDLG fd;
-
- // clear all fields to zero before proceeding
- memset(&fd,0,sizeof(FILEDLG));
-
- // set up file dialog
- fd.cbSize=sizeof(FILEDLG);
- fd.fl=FDS_CENTER|FDS_OPEN_DIALOG;
- fd.pszTitle=(PSZ)"Load spellbook from file:";
- strcpy(fd.szFullFile,"*.sbk");
-
- if (!WinFileDlg(HWND_DESKTOP,
- HWND_DESKTOP,
- &fd)) return(false);
-
- if (fd.lReturn==DID_OK) {
- new bookwindow(fd.szFullFile,false);
- return(true);
- }
- else return(false);
- }
-
-
- // insert fields for name and spell level
- boolean bookwindow::insert_fields() {
- FIELDINFOINSERT fiins;
- PFIELDINFO pfi;
- int i;
- int fields = 10;
- CNRINFO cnrinfo;
-
- static const PSZ TitleData[] = {NULL,
- "Name of Spell",
- "Lvl",
- "Cast",
- "Range",
- "Duration",
- "Area",
- "School / Sphere",
- "Comp.",
- "Save"};
-
- static const ULONG flData[] = {CFA_BITMAPORICON,
- CFA_STRING|CFA_HORZSEPARATOR,
- CFA_ULONG|CFA_SEPARATOR|
- CFA_INVISIBLE|CFA_HORZSEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE|CFA_SEPARATOR,
- CFA_STRING|CFA_HORZSEPARATOR|
- CFA_INVISIBLE};
-
- // these are the correct macro expansions of:
- //FIELDOFFSET(spellrecord,level)
- // and so on...
- static const ULONG offStruct[] = {((ULONG)&(((spellrecord *)0)->core.hptrMiniIcon)),
- ((ULONG)&(((spellrecord *)0)->core.pszText)),
- ((ULONG)&(((spellrecord *)0)->level)),
- ((ULONG)&(((spellrecord *)0)->cast)),
- ((ULONG)&(((spellrecord *)0)->range)),
- ((ULONG)&(((spellrecord *)0)->duration)),
- ((ULONG)&(((spellrecord *)0)->area)),
- ((ULONG)&(((spellrecord *)0)->sphereschool)),
- ((ULONG)&(((spellrecord *)0)->components)),
- ((ULONG)&(((spellrecord *)0)->save))};
-
-
- // get memory for fields
- pfi = pfieldinfo = (PFIELDINFO)WinSendMsg(hwndcnr,
- CM_ALLOCDETAILFIELDINFO,
- MPFROMLONG(fields),
- NULL);
-
- // initialize them
- for (i=0; i<fields; i++) {
- pfi->cb = sizeof(FIELDINFO);
- pfi->flData = flData[i] | CFA_FIREADONLY;
- pfi->flTitle = CFA_FITITLEREADONLY | CFA_LEFT;
- pfi->pTitleData = (PVOID)TitleData[i];
- pfi->offStruct = offStruct[i];
- pfi = pfi->pNextFieldInfo;
- }
-
- // initialize FIELDINFOINSERT
- fiins.cb = sizeof fiins;
- fiins.pFieldInfoOrder = (PFIELDINFO)CMA_FIRST;
- fiins.cFieldInfoInsert = fields;
- fiins.fInvalidateFieldInfo = TRUE;
-
- // tell cnr to insert it
- WinSendMsg(hwndcnr,
- CM_INSERTDETAILFIELDINFO,
- MPFROMP(pfieldinfo),
- MPFROMP(&fiins));
-
- // place vertical scroll var after "name" column
- cnrinfo.xVertSplitbar = splitbarpos;
- cnrinfo.pFieldInfoLast = pfieldinfo->pNextFieldInfo; // 2nd field
- WinSendMsg(hwndcnr,
- CM_SETCNRINFO,
- MPFROMP(&cnrinfo),
- MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
-
- return(true);
- }
-
- // tell container which details fields to show
- void bookwindow::show_fields() {
- ULONG f=details_fields;
- int i;
- ULONG flag=1;
- PFIELDINFO pfi = pfieldinfo;
-
- // move to 3rd field.
- pfi = pfi->pNextFieldInfo;
- pfi = pfi->pNextFieldInfo;
-
- for (i=0; i<8; i++) {
- if (f & flag) { // &= !CFA_INVISIBLE doesn't work.
- pfi->flData |= CFA_INVISIBLE;
- pfi->flData ^= CFA_INVISIBLE;
- }
- else pfi->flData |= CFA_INVISIBLE;
- flag *= 2;
- pfi = pfi->pNextFieldInfo;
- }
-
- WinSendMsg(hwndcnr,
- CM_INVALIDATEDETAILFIELDINFO,
- 0,0);
- }
-
- // query split bar pos, as while saving window
- void bookwindow::query_splitbar() {
- CNRINFO cnrinfo;
-
- WinSendMsg(hwndcnr,
- CM_QUERYCNRINFO,
- MPFROMP(&cnrinfo),
- (MPARAM)sizeof(cnrinfo));
- splitbarpos = cnrinfo.xVertSplitbar;
- }
-
- // load and set window attributes for a bookwindow
- void bookwindow::load_attr() {
- SWP swp;
- book_attr ba;
- boolean foundpos;
- ULONG ultemp;
- long ltemp;
- SHORT w,h;
-
- // get default values
- WinQueryTaskSizePos(hab,0,&swp);
- ba.view = CV_NAME;
- ba.miniicon = CV_MINI;
- ba.splitbarpos = 250;
- ba.x = swp.x;
- ba.y = swp.y;
- ba.cx = swp.cx;
- ba.cy = swp.cy;
- ba.foregroundcolor = 0;
- ba.backgroundcolor = 0;
- ba.fontnamesize[0] = (char)0;
- ba.details_fields = FL_LEVEL | FL_SPHERESCHOOL;
-
- foundpos=false;
- if (master_list_win) {
- ultemp=sizeof(book_attr);
- PrfQueryProfileData(hini,
- "spellbook",
- "bookattr",
- &ba,
- &ultemp);
- foundpos=true;
- }
- else if (filename) {
- ltemp=sizeof(book_attr);
- if (getEA(filename,
- ".bookattr",
- &ba,
- <emp)==0)
- foundpos=true;
- }
-
- if (!foundpos) {
- // get generic width, height; use random x,y;
- ultemp=sizeof(book_attr);
- PrfQueryProfileData(hini,
- "spellbook",
- "newbookattr",
- &ba,
- &ultemp);
- ba.x = swp.x;
- ba.y = swp.y;
- }
-
- // make sure we aren't off screen.
- w = WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
- h = WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
- if (ba.x+ba.cx > w) ba.x = w - ba.cx;
- if (ba.y+ba.cy > h) ba.y = h - ba.cy;
-
- // set the position & size
- hwndframe = WinQueryWindow(hwnd,QW_PARENT);
- WinSetWindowPos(hwndframe,
- HWND_TOP,
- ba.x,ba.y,
- ba.cx,ba.cy,
- SWP_SIZE|SWP_SHOW|SWP_MOVE|SWP_ZORDER);
-
- view = ba.view;
- miniicon = ba.miniicon;
- splitbarpos = ba.splitbarpos;
- details_fields = ba.details_fields;
-
- // set colors and fonts
- if (ba.foregroundcolor)
- WinSetPresParam(hwndcnr,
- PP_FOREGROUNDCOLOR,
- sizeof(ULONG),
- &ba.foregroundcolor);
- if (ba.backgroundcolor)
- WinSetPresParam(hwndcnr,
- PP_BACKGROUNDCOLOR,
- sizeof(ULONG),
- &ba.backgroundcolor);
- if (ba.fontnamesize[0]) {
- fontname = strdup(ba.fontnamesize);
- WinSetPresParam(hwndcnr,
- PP_FONTNAMESIZE,
- (ULONG)(strlen(fontname)+1),
- fontname);
- }
- }
-
- // save visible attributes of bookwindow
- void bookwindow::save_attr() {
- SWP swp;
- book_attr ba;
- ULONG attrfound;
- ULONG attrvalue[32];
- ULONG rc;
-
- query_splitbar();
- WinQueryWindowPos(hwndframe,&swp);
- ba.view = view;
- ba.miniicon = miniicon;
- ba.splitbarpos = splitbarpos;
- ba.x = swp.x;
- ba.y = swp.y;
- ba.cx = swp.cx;
- ba.cy = swp.cy;
- ba.details_fields = details_fields;
-
- rc=WinQueryPresParam(hwndcnr,
- PP_FOREGROUNDCOLOR,
- 0,
- &attrfound,
- sizeof(attrvalue),
- (PVOID)attrvalue,
- 0);
- if (rc && (attrfound == PP_FOREGROUNDCOLOR))
- memcpy(&ba.foregroundcolor,attrvalue,sizeof(ULONG));
- else ba.foregroundcolor=0;
-
- rc=WinQueryPresParam(hwndcnr,
- PP_BACKGROUNDCOLOR,
- 0,
- &attrfound,
- sizeof(attrvalue),
- (PVOID)attrvalue,
- 0);
- if (rc && (attrfound == PP_BACKGROUNDCOLOR))
- memcpy(&ba.backgroundcolor,attrvalue,sizeof(ULONG));
- else ba.backgroundcolor=0;
-
- rc=WinQueryPresParam(hwndcnr,
- PP_FONTNAMESIZE,
- 0,
- &attrfound,
- sizeof(attrvalue),
- (PVOID)attrvalue,
- 0);
- if (rc && (attrfound == PP_FONTNAMESIZE)) {
- if (rc>127) rc=127;
- ba.fontnamesize[rc]=(char)0;
- memcpy(ba.fontnamesize,attrvalue,rc);
- }
- else ba.fontnamesize[0]=(char)0;
-
-
- if (master_list_win) {
- PrfWriteProfileData(hini,
- "spellbook",
- "bookattr",
- &ba,
- sizeof(book_attr));
- }
- else if (filename) {
- putEA(filename,
- ".bookattr",
- &ba,
- sizeof(book_attr));
- }
- else {
- PrfWriteProfileData(hini,
- "spellbook",
- "newbookattr",
- &ba,
- sizeof(book_attr));
- }
- }
-
- // add spell to a window, after spell "where" (and to book also)
- boolean bookwindow::add_spell(spell *s, spellrecord *where) {
- spellrecord *newrecord;
- LONG extrabytes;
- HPOINTER myicon;
- priestspell *ps = (priestspell *)s;
-
- extrabytes=(LONG)(sizeof(spellrecord)-sizeof(RECORDCORE));
- // tell the container to allocate memory for new record
- newrecord=(spellrecord *)WinSendMsg(hwndcnr,
- CM_ALLOCRECORD,
- MPFROMLONG(extrabytes),
- (MPARAM)1);
-
- // set up record
- newrecord->core.flRecordAttr=0;
- newrecord->s=s;
- newrecord->level = (ULONG)s->level;
- newrecord->cast = ps->casttime;
- newrecord->range = ps->range;
- newrecord->duration = ps->duration;
- newrecord->area = ps->area;
- if (s->type=='M')
- newrecord->sphereschool = ps->school;
- else
- newrecord->sphereschool = ps->sphere;
- newrecord->components = ps->components;
- newrecord->save = ps->save;
- newrecord->core.pszIcon=(PSZ)s->name;
- newrecord->core.pszText=(PSZ)s->name;
- newrecord->core.pszName=(PSZ)s->name;
- myicon=lookup_icon(s);
- newrecord->core.hptrIcon=myicon;
- newrecord->core.hptrMiniIcon=myicon;
- newrecord->core.preccNextRecord=0;
-
- // tell the container to add the record
- RECORDINSERT ri;
- ri.cb=sizeof(RECORDINSERT);
- if (where==NULL)
- ri.pRecordOrder=(PRECORDCORE)CMA_END;
- else
- ri.pRecordOrder=&(where->core);
- ri.pRecordParent=NULL;
- ri.fInvalidateRecord=FALSE;
- ri.zOrder=CMA_TOP;
- ri.cRecordsInsert=1;
-
- WinSendMsg(hwndcnr,
- CM_INSERTRECORD,
- MPFROMP(newrecord),
- MPFROMP(&ri));
-
- // add to spellbook, also
- if (where==NULL) // add at end.
- newrecord->spl = sb->add_spell(*s, sb->last);
- else // add after where
- newrecord->spl = sb->add_spell(*s, where->spl);
-
- if (!readonly) saved=false;
- return(true);
- }
-
- // add a new spell to a window
- boolean bookwindow::add_new_spell() {
- static int i=0;
- char *buffer;
-
- spell *newspell;
-
- // edit new spell in editor
-
- // load new spell into window
- newspell=new magespell;
- buffer=new char[100];
- sprintf(buffer,"New spell # %d\n",i++);
- newspell->name=buffer;
-
- // insert spell after first emphasized record, if any
- spellrecord *insafter;
- insafter=(spellrecord *)
- PVOIDFROMMR(WinSendMsg(hwndcnr,
- CM_QUERYRECORDEMPHASIS,
- MPFROMP(CMA_FIRST),
- MPFROMSHORT(CRA_SELECTED)));
-
- if (insafter==NULL)
- add_spell(newspell);
- else
- add_spell(newspell,insafter);
-
- refresh();
- return(true);
- }
-
- // delete a spell from window and from the book.
- boolean bookwindow::delete_spell(spellrecord *deleteme) {
- PVOID removeme=&(deleteme);
-
- // remove from spellbook
- sb->del_spell(deleteme->spl);
-
- // and from window
- WinSendMsg(hwndcnr,
- CM_REMOVERECORD,
- MPFROMP(removeme),
- MPFROM2SHORT(1,CMA_FREE));
-
- if (!readonly) saved=false;
- return(true);
- }
-
- // delete all selected spells from window, then update the window.
- boolean bookwindow::delete_selected_spells() {
- spellrecord *deleteme;
-
- while (deleteme=(spellrecord *)
- WinSendMsg(hwndcnr,
- CM_QUERYRECORDEMPHASIS,
- MPFROMP(CMA_FIRST),
- MPFROMSHORT(CRA_SELECTED)))
- delete_spell(deleteme);
-
- refresh();
- return(true);
- }
-
- // is a given record selected?
- boolean selected(spellrecord *x) {
- if (x->core.flRecordAttr & CRA_SELECTED) return(true);
- else return(false);
- }
-
- // refresh spell window
- boolean bookwindow::refresh() {
- WinSendMsg(hwndcnr,
- CM_INVALIDATERECORD,
- (MPARAM)0,
- MPFROM2SHORT(0,CMA_REPOSITION));
- return(true);
- }
-
- // change spell, update screen and spellbook.
- boolean bookwindow::change_spell(spell *oldsp, spell *newsp) {
- spellrecord *found;
- SEARCHSTRING oldname;
-
- oldname.pszSearch=(PSZ)oldsp->name;
- oldname.fsPrefix=TRUE;
- oldname.fsCaseSensitive=TRUE;
- oldname.usView=CV_NAME;
- oldname.cb=sizeof(oldname);
-
- found=(spellrecord *)WinSendMsg(hwndcnr,
- CM_SEARCHSTRING,
- (MPARAM)(&oldname),
- (MPARAM)CMA_FIRST);
-
- if (!found) return(false);
-
- // name match does not imply a real match.
- if (found->s == oldsp) {
- add_spell(newsp,found);
- delete_spell(found);
- refresh();
- return (true);
- }
- return(false);
- }
-
- void show_spell(bookwindow *mywin, MPARAM whichspell) {
- char buffer[256];
- PNOTIFYRECORDENTER pn;
- spellrecord *selected;
- spellwindow *child;
-
- pn = (PNOTIFYRECORDENTER)whichspell;
- selected = (spellrecord *)(pn->pRecord);
- if (selected)
- child = new spellwindow(selected->spl, mywin);
- }
-
- void find_and_show_spell(bookwindow *mywin, spell *s) {
- spellrecord *found;
- SEARCHSTRING oldname;
- spellwindow *child;
-
- oldname.pszSearch=(PSZ)s->name;
- oldname.fsPrefix=TRUE;
- oldname.fsCaseSensitive=TRUE;
- oldname.usView=CV_NAME;
- oldname.cb=sizeof(oldname);
-
- found=(spellrecord *)WinSendMsg(mywin->hwndcnr,
- CM_SEARCHSTRING,
- (MPARAM)(&oldname),
- (MPARAM)CMA_FIRST);
-
- if (!found) return;
-
- // name match does not imply a real match.
- if (found->s == s)
- child = new spellwindow(found->spl, mywin);
- }
-
- MRESULT drop_spell(bookwindow *mywin, PCNRDRAGINFO pcdi) {
- char buffer[256];
- int items;
- PDRAGINFO pdraginfo;
-
- pdraginfo=pcdi->pDragInfo;
-
- // make sure we can access the draginfo structure
- if (!DrgAccessDraginfo(pdraginfo))
- return(MRFROM2SHORT(DOR_NODROPOP,0));
-
- // how many items?
- items=DrgQueryDragitemCount(pdraginfo);
-
- spellrecord *dropped_on;
- PDRAGITEM pditem;
- spellrecord *dropping;
- // add each item
- if (pcdi->pRecord) { // if dropped on another spell
- for (int i=items-1; i>=0; i--) {
- pditem=DrgQueryDragitemPtr(pdraginfo,i);
-
- // add after record it was dropped on
- dropped_on=(spellrecord *)(pcdi->pRecord);
- dropping=(spellrecord *)pditem->ulItemID;
- mywin->add_spell(dropping->s,dropped_on);
-
- // dropped on same window -> delete old item
- if (mywin->hwnd==pditem->hwndItem)
- mywin->delete_spell(dropping);
- }
- }
- else { // dropped on empty space
- for (int i=0; i<items; i++) {
- pditem=DrgQueryDragitemPtr(pdraginfo,i);
-
- // add at end
- dropping=(spellrecord *)pditem->ulItemID;
- mywin->add_spell(dropping->s);
-
- // dropped on same window -> delete old item
- if (mywin->hwnd==pditem->hwndItem)
- mywin->delete_spell(dropping);
- }
- }
-
- mywin->refresh();
-
- DrgFreeDraginfo(pdraginfo);
-
- return((MRESULT)0);
- }
-
-
- // something is being dragged over the container
- MRESULT drag_over(bookwindow *mywin, PDRAGINFO pdraginfo) {
- USHORT usIndicator=DOR_DROP,usOperation;
- int items;
-
- if (mywin->readonly) return(MRFROM2SHORT(DOR_NEVERDROP,DO_COPY));
-
- // make sure we can access the draginfo structure
- if (!DrgAccessDraginfo(pdraginfo))
- return(MRFROM2SHORT(DOR_NODROPOP,0));
-
- // how many items?
- items=DrgQueryDragitemCount(pdraginfo);
-
- // check each item
- for (int i=0; i<items; i++) {
- PDRAGITEM pditem;
- pditem=DrgQueryDragitemPtr(pdraginfo,i);
- if (!DrgVerifyRMF(pditem,(PSZ)"Spell",(PSZ)"Spell"))
- usIndicator=DOR_NEVERDROP;
- }
-
- // only operation for spells
- usOperation=DO_COPY;
-
- DrgFreeDraginfo(pdraginfo);
- return(MRFROM2SHORT(usIndicator,usOperation));
- }
-
- BOOL init_drag(bookwindow *mywin,PCNRDRAGINIT pcdi) {
- char buffer[256];
- ULONG items;
- spellrecord *selected;
-
- // no dragging from empty space
- if (pcdi->pRecord==NULL) return(FALSE);
-
- // if record is selected, it may be part of a group
- if (pcdi->pRecord->flRecordAttr & CRA_SELECTED) {
- // find # of items being dragged
- items=0;
- selected=(spellrecord *)WinSendMsg(mywin->hwndcnr,
- CM_QUERYRECORDEMPHASIS,
- MPFROMP(CMA_FIRST),
- MPFROMSHORT(CRA_SELECTED));
- while (selected!=NULL) {
- selected=(spellrecord *)WinSendMsg(mywin->hwndcnr,
- CM_QUERYRECORDEMPHASIS,
- MPFROMP(selected),
- MPFROMSHORT(CRA_SELECTED));
- items++;
- }
- }
- else items=1;
-
- // no items dragged? shouldn't get here.
- if (items==0) return (FALSE);
-
- // get DRAGINFO structure
- PDRAGINFO pdraginfo;
- pdraginfo=DrgAllocDraginfo(items);
-
- DRAGITEM dragitem;
-
- // common parts of DRAGITEM structure
- dragitem.hwndItem=mywin->hwnd;
- dragitem.hstrType=DrgAddStrHandle((PSZ)"Spell");
- dragitem.hstrRMF=DrgAddStrHandle((PSZ)"<Spell,Spell>");
- dragitem.hstrContainerName=NULL;
- dragitem.fsControl=0;
- dragitem.fsSupportedOps=DO_COPYABLE;
-
- // add each dragged item
- selected=(spellrecord *)CMA_FIRST;
- for (int i=0; i<items; i++) {
- if (items==1)
- // if there's only 1 item, it must be the one direct
- // manipulation started on.
- selected=(spellrecord *)pcdi->pRecord;
- else
- selected=(spellrecord *)WinSendMsg(mywin->hwndcnr,
- CM_QUERYRECORDEMPHASIS,
- MPFROMP(selected),
- MPFROMSHORT(CRA_SELECTED));
-
- dragitem.hstrSourceName=DrgAddStrHandle(selected->core.pszText);
- dragitem.hstrTargetName=dragitem.hstrSourceName;
- dragitem.ulItemID=(ULONG)selected;
-
- // add dragitem to draginfo structure
- DrgSetDragitem(pdraginfo,&dragitem,sizeof(DRAGITEM),i);
- }
-
- DRAGIMAGE dimg;
- if (items==1)
- dimg.hImage=lookup_icon(selected->s);
- else dimg.hImage=dragicon;
- dimg.fl=DRG_ICON;
- dimg.cb=sizeof(DRAGIMAGE);
- dimg.cxOffset=0;
- dimg.cyOffset=0;
-
- pdraginfo->hwndSource=mywin->hwnd;
- HWND destination;
- destination = DrgDrag(mywin->hwndcnr,pdraginfo,&dimg,1,VK_ENDDRAG,NULL);
-
- return(TRUE);
- }
-
- MRESULT savequit(bookwindow *mywin) {
- // has window been saved?
- if ((!mywin->readonly) && (!mywin->saved)) {
- ULONG response;
- response= WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)"Save spellbook before closing?",
- (PSZ)"Spellbook changed since last save",
- 102,
- MB_YESNOCANCEL|MB_ICONQUESTION);
- if (response==MBID_YES) {
- if (!mywin->save_book(false)) return((MRESULT)FALSE);
- }
- else if (response==MBID_CANCEL) return((MRESULT)FALSE);
- }
-
- if (first->next==NULL) { //this is the last window
- ULONG response = WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)"Closing the last spellbook will end the program. Are you sure?",
- (PSZ)"Warning!",
- 102,
- MB_YESNO|MB_ICONEXCLAMATION);
- if (response==MBID_YES)
- WinPostMsg(mywin->hwnd,WM_QUIT,0,0);
- }
- else {
- delete mywin;
- return ((MRESULT)TRUE);
- }
-
- return ((MRESULT)TRUE);
- }
-
- // show spellbook in given mode
- void bookwindow::show() {
- CNRINFO cnrInfo;
- MENUITEM mi;
- HWND hwndmenu;
- static LONG iconcx = 0;
- static LONG iconcy = 0;
-
- if (iconcx==0) {
- // find "normal" icon size from system values
- iconcx = WinQuerySysValue(HWND_DESKTOP,
- SV_CXICON);
- iconcy = WinQuerySysValue(HWND_DESKTOP,
- SV_CYICON);
- }
-
- // check items on main menu
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_TEXT,
- view & CV_TEXT ? TRUE : FALSE);
-
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_NAME,
- view & CV_NAME ? TRUE : FALSE);
-
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_ICON,
- view & CV_ICON ? TRUE : FALSE);
-
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_DETAIL,
- view & CV_DETAIL ? TRUE : FALSE);
-
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_FULLICON,
- miniicon ? FALSE : TRUE);
-
- check_menu_item(hwndframe,
- VIEW_SUBMENU,
- V_MINIICON,
- miniicon ? TRUE : FALSE);
-
- // check items on popup menus
- WinCheckMenuItem(hwndpopup,
- V_TEXT,
- view & CV_TEXT ? TRUE : FALSE);
-
- WinCheckMenuItem(hwndpopup,
- V_NAME,
- view & CV_NAME ? TRUE : FALSE);
-
- WinCheckMenuItem(hwndpopup,
- V_ICON,
- view & CV_ICON ? TRUE : FALSE);
-
- WinCheckMenuItem(hwndpopup,
- V_DETAIL,
- view & CV_DETAIL ? TRUE : FALSE);
-
- WinCheckMenuItem(hwndpopup,
- V_FULLICON,
- miniicon ? FALSE : TRUE);
-
- WinCheckMenuItem(hwndpopup,
- V_MINIICON,
- miniicon ? TRUE : FALSE);
-
- // get "miniicon" view in details mode; not automatic
- if ((view & CV_DETAIL) && (miniicon)) {
- cnrInfo.slBitmapOrIcon.cx = iconcx / 2;
- cnrInfo.slBitmapOrIcon.cy = iconcy / 2;
- }
- else {
- cnrInfo.slBitmapOrIcon.cx = iconcx;
- cnrInfo.slBitmapOrIcon.cy = iconcy;
- }
-
- // set view
- cnrInfo.flWindowAttr = view | miniicon |
- CA_DETAILSVIEWTITLES;
-
- // tell the container to change view
- WinSendMsg(hwndcnr,
- CM_SETCNRINFO,
- MPFROMP(&cnrInfo),
- MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
- }
-
- // change a spell in all books
- void change_all(spell *old_spell, spell *mod_spell) {
- bookwindow *ptr;
-
- for (ptr=first; ptr!=NULL; ptr=ptr->next) {
- ptr->change_spell(old_spell,mod_spell);
- }
- }
-
- // window procedure for book windows
- MRESULT EXPENTRY book_window_func(HWND hwnd, ULONG msg,
- MPARAM param1, MPARAM param2) {
- short cx,cy;
- char *txt,buffer[256];
- bookwindow *mywin;
- bookwindow *nsw;
- ULONG ultemp;
- SWP winpos;
- POINTL ptl;
- HWND hwndmenu;
- static spellrecord *menurecord=NULL;
- spellwindow *child;
-
- switch (msg) {
-
- case WM_ERASEBACKGROUND:
- return (MRESULT)TRUE;
-
- case WM_CREATE:
- // save book handle in first window
- first->hwnd=hwnd;
-
- // save pointer to my class in window word
- WinSetWindowPtr(hwnd,
- 0,
- first);
-
- // find out my size (client window)
- WinQueryWindowPos(hwnd,&winpos);
- cx=winpos.cx;
- cy=winpos.cy;
-
- // load in popup menu
- first->hwndpopup=WinLoadMenu(hwnd,NULLHANDLE,BOOK_POPUP_MENU);
- first->hwndsppopup=WinLoadMenu(hwnd,NULLHANDLE,SPELL_POPUP_MENU);
-
- // create container filling whole window
- first->hwndcnr=
- WinCreateWindow(
- hwnd,
- WC_CONTAINER,
- 0,
- CCS_AUTOPOSITION | // Auto position
- CCS_EXTENDSEL, // Extended selection
- (LONG)0,
- (LONG)0,
- (LONG)cx,
- (LONG)cy,
- hwnd,
- HWND_TOP,
- windows++,
- NULL,
- NULL);
-
- // load window attributes from INI or EA's.
- first->load_attr();
-
- // add fields for details view info
- first->insert_fields();
- first->show_fields();
-
- // and activate it
- first->show();
- WinShowWindow(first->hwndcnr,TRUE);
-
- break;
-
- case WM_SIZE:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
-
- cx=SHORT1FROMMP(param2);
- cy=SHORT2FROMMP(param2);
- // tell the container to change its size
- WinSetWindowPos(mywin->hwndcnr,0,0,0,cx,cy,SWP_SIZE);
-
- break;
-
- // is menu valid?
- case WM_INITMENU:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
-
- switch(SHORT1FROMMP(param1)) {
- case SPELL_SUBMENU:
- BOOL ok;
-
- if (mywin->readonly) ok=FALSE;
- else ok=TRUE;
-
- enable_menu_item(HWNDFROMMP(param2), ADDSPELL, ok);
- enable_menu_item(HWNDFROMMP(param2), DELSPELL, ok);
- }
- break;
-
- // ACK from object window... done with whatever it was doing
- case WM_USER_ACK:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- mywin->enable();
- break;
-
- case WM_USER_CREATE_SUBSET:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- mywin->disable();
- WinPostMsg(mywin->hwndobject,
- WM_USER_CREATE_SUBSET,
- param1,param2);
- break;
-
- case WM_USER_DETAILS_FIELDS:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- mywin->details_fields = (ULONG)param1;
- mywin->show_fields();
- break;
-
- // mouse is moving, display clock if busy
- case WM_MOUSEMOVE:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- ultemp = mywin->busy ? SPTR_WAIT : SPTR_ARROW;
- WinSetPointer(HWND_DESKTOP,
- WinQuerySysPointer(HWND_DESKTOP,ultemp,FALSE));
- return (MRESULT)TRUE;
- break;
-
- case WM_USER_SORT:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- mywin->disable();
- WinPostMsg(mywin->hwndobject,
- WM_USER_SORT,
- param1,param2);
- break;
-
- /*
- case HM_HELPSUBITEM_NOT_FOUND:
- sprintf(buffer,"Context: %d, topic: %d, subtopic: %d",
- (ULONG)param1,
- SHORT1FROMMP(param2),
- SHORT2FROMMP(param2));
- WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)buffer,
- "Help Subtable Not Found",
- 102,
- MB_OK);
- return (MRESULT)FALSE;
- break;
-
- case HM_ERROR:
- sprintf(buffer,"%d",(ULONG)param1);
- WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)buffer,
- "Help Error",
- 102,
- MB_OK);
- return (MRESULT)FALSE;
- break;
- */
-
- // command from menu or dialog
- case WM_COMMAND:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
-
- switch(SHORT1FROMMP(param1)) {
- case ADDSPELL:
- mywin->add_new_spell();
- break;
-
- case DELSPELL:
- mywin->delete_selected_spells();
- break;
-
- case MENUSHOWSPELL:
- if (menurecord) {
- child = new spellwindow(menurecord->spl, mywin);
- menurecord = NULL;
- }
- break;
-
- case MENUDELSPELL:
- if (menurecord) {
- if (selected(menurecord)) mywin->delete_selected_spells();
- else {
- mywin->delete_spell(menurecord);
- mywin->refresh();
- }
- menurecord = NULL;
- }
- else
- mywin->delete_selected_spells();
- break;
-
- case MASTER:
- // make a new master list window
- new bookwindow(NULL,true);
- break;
-
- case SUBSET:
- WinLoadDlg(HWND_DESKTOP,
- hwnd,
- select_dlg_func,
- 0L,
- SELECT_DLG,
- NULL);
- break;
-
- case SORTBOOK:
- WinLoadDlg(HWND_DESKTOP,
- hwnd,
- sort_dlg_func,
- 0L,
- SORT_DLG,
- mywin);
- break;
-
- case RENAME:
- WinDlgBox(HWND_DESKTOP,
- hwnd,
- rename_dlg_func,
- 0L,
- RENAME_DLG,
- NULL);
- break;
-
- case ABOUT:
- WinDlgBox(HWND_DESKTOP,
- hwnd,
- about_dlg_func,
- 0L,
- ABOUT_DLG,
- NULL);
- break;
-
- case HELP_INDEX:
- WinSendMsg(hwndhelp,
- HM_HELP_INDEX,
- 0,0);
- break;
-
- case HELP_GENERAL:
- WinSendMsg(hwndhelp,
- HM_GENERAL_HELP,
- 0,0);
- break;
-
- case HELP_HELP:
- WinSendMsg(hwndhelp,
- HM_DISPLAY_HELP,
- 0,0);
- break;
-
- case V_NAME:
- mywin->view = CV_NAME;
- mywin->show();
- break;
-
- case V_ICON:
- mywin->view = CV_ICON;
- mywin->show();
- break;
-
- case V_DETAIL:
- mywin->view = CV_DETAIL;
- mywin->show();
- break;
-
- case V_DETAILSFIELDS:
- WinDlgBox(HWND_DESKTOP,
- hwnd,
- fields_dlg_func,
- 0L,
- FIELD_DLG,
- mywin);
- break;
-
- case V_TEXT:
- mywin->view = CV_TEXT;
- mywin->show();
- break;
-
- case V_MINIICON:
- mywin->miniicon = CV_MINI;
- mywin->show();
- break;
-
- case V_FULLICON:
- mywin->miniicon = 0;
- mywin->show();
- break;
-
- case NEWBOOK:
- new bookwindow;
- break;
-
- case SAVETITLES:
- mywin->save_book(true);
- break;
-
- case SAVEBOOK:
- mywin->save_book(false);
- break;
-
- case LOADBOOK:
- load_book();
- break;
-
- case CLOSEBOOK:
- WinSendMsg(mywin->hwnd,
- WM_CLOSE,
- 0,
- 0);
- break;
-
- case QUITPROGRAM:
- boolean allsaved=true;
- bookwindow *ptr;
- for (ptr=first; ptr!=NULL; ptr=ptr->next)
- if (ptr->saved==false) allsaved=false;
-
- if (!allsaved) {
- ULONG response = WinMessageBox(HWND_DESKTOP,
- HWND_DESKTOP,
- (PSZ)"End the program without saving all spellbooks?",
- (PSZ)"Warning!",
- 102,
- MB_YESNO|MB_ICONEXCLAMATION);
- if (response==MBID_NO) break;
- }
- WinPostMsg(mywin->hwnd,WM_QUIT,0,0);
- }
- break;
-
- // message from container
- case WM_CONTROL:
- PCNRDRAGINFO pcdi;
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
-
- switch (SHORT2FROMMP(param1)) {
- case CN_ENTER:
- show_spell(mywin, param2);
- return ((MRESULT)TRUE);
- break;
-
- case CN_INITDRAG:
- if (init_drag(mywin,(PCNRDRAGINIT)param2))
- return ((MRESULT)FALSE);
- else
- return ((MRESULT)TRUE);
- break;
-
- case CN_DRAGOVER:
- pcdi=(PCNRDRAGINFO)param2;
- return drag_over(mywin,pcdi->pDragInfo);
- break;
-
- case CN_DROP:
- pcdi=(PCNRDRAGINFO)param2;
- return drop_spell(mywin,pcdi);
- break;
-
- // show container popup menu
- case CN_CONTEXTMENU:
- if (param2) {
- hwndmenu = mywin->hwndsppopup;
- menurecord = (spellrecord *)param2;
-
- enable_menu_item(hwndmenu,
- MENUDELSPELL,
- (mywin->readonly) ? FALSE : TRUE);
- }
- else
- hwndmenu = mywin->hwndpopup;
-
- // get current postion to pop up the menu
- WinQueryMsgPos(hab, &ptl);
-
- WinPopupMenu(HWND_DESKTOP,hwnd,hwndmenu,
- ptl.x,
- ptl.y,
- NULL,
- PU_HCONSTRAIN | PU_VCONSTRAIN |
- PU_KEYBOARD | PU_MOUSEBUTTON1 |
- PU_MOUSEBUTTON2 |
- PU_MOUSEBUTTON3);
- return((MRESULT)0);
- break;
-
- }
- break;
-
- // user wants to close the window
- case WM_CLOSE:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- return savequit(mywin);
- break;
-
- // window destroyed
- case WM_DESTROY:
- mywin=(bookwindow *)WinQueryWindowPtr(hwnd,0);
- if ((mywin->master_list_win) && (!mywin->saved))
- mywin->sb->quicksave(quick_master_name);
- mywin->save_attr();
- break;
- }
- return WinDefWindowProc(hwnd, msg, param1, param2);
- }
-