📄 mainwind.cpp
字号:
/************************************************************************
* mainwind.cpp *
* This is one of a few files which contain some old code, a lot of *
* hacks, a lot of hastily stuffed lines and variables, etc, and is in *
* in need of an overhaul. Its also why I left commenting it until the *
* last four files (disasm,fileload,dasm and this one!). Whilst making *
* these comments I have taken a small opportunity to tidy it a little. *
* This file controls output to the main window. It keeps a small buffer *
* of disassembled lines, and it uses this buffer to repaint the main *
* window when WM_PAINT requests are received. *
* Whenever the disassembly is changed or the user scrolls there is a *
* windowupdate request sent to the scheduler with a high priority. *
* When the windowupdate is processed it is passed to the windowupdate *
* or scroller function in disio. disio will regenerate the buffer as *
* required and then invalidate the main window so that a repaint is *
* done. *
* The functions here include basic formatted output to the buffer as *
* well as the window repaints. Repaints will not be done while the *
* buffer is being updated, but will wait for the buffer update to *
* finish and then do the repaint. *
* The functions also use extensive critical sections which ensure that *
* we do not start clearing the buffer during a window update, etc *
************************************************************************/
#include <windows.h>
#include <stdio.h>
#include "mainwind.h"
#include "dasm.h"
#include "debug.h"
/************************************************************************
* global variables *
* - the MainBuff is the buffered output used for repainting *
************************************************************************/
UINT lastline=0;
volatile bool bufferready=true;
char MainBuff[buffer_lines*max_length+1000]; // lets hope it doesn't overflow
// wvsprintf sucks!
UINT nScreenRows;
UINT usersel; // the line which is the current user selection. (line number).
unsigned int rrr=0,cyc;
int hpos=0;
bool userselonscreen=false;
/************************************************************************
* horizscroll *
* - hpos keeps track of the horizontal scroll which determines where *
* from each buffer line we start printing the output *
************************************************************************/
void horizscroll(int amount)
{ EnterCriticalSection(&cs);
hpos+=amount;
if(hpos<0)
hpos=0; // max-size checked in dopaint.
LeaveCriticalSection(&cs);
InvalidateRect(mainwindow,NULL,true);
}
/************************************************************************
* horizscrollto *
* - this is used when the horizontal scrollbar control is dragged and *
* dropped to change the hpos offset to the new place (maximum *
* horizontal size is fixed in Borg) *
************************************************************************/
void horizscrollto(int place)
{ EnterCriticalSection(&cs);
hpos=place;
LeaveCriticalSection(&cs);
InvalidateRect(mainwindow,NULL,true);
}
/************************************************************************
* ClearBuff *
* - This should be called before each reworking of the buffer. It *
* clears the buffer and stops any repainting from taking place. *
* - It also resets the line pointer to the start of the buffer. *
************************************************************************/
void ClearBuff(void)
{ int i;
EnterCriticalSection(&cs);
for(i=0;i<buffer_lines;i++)
{ MainBuff[i*max_length]=0;
}
lastline=0;
bufferready=false;
LeaveCriticalSection(&cs);
}
/************************************************************************
* DoneBuff *
* - This should be called after a reworking of the buffer. It reenables *
* window repainting. *
************************************************************************/
void DoneBuff(void)
{ EnterCriticalSection(&cs);
bufferready=true;
LeaveCriticalSection(&cs);
}
/************************************************************************
* PrintBuff *
* - This is the printf of the buffer and is similar to wvsprintf but *
* output is to the main buffer. Note that the line pointer is moved *
* on after a call, so we move to the next line automatically. *
************************************************************************/
// adds next line to the buffer.
void PrintBuff(char *szFormat,...)
{ EnterCriticalSection(&cs);
va_list vaArgs;
va_start(vaArgs,szFormat);
if(lastline<buffer_lines-1)
{ wvsprintf(&MainBuff[lastline*max_length],szFormat,vaArgs);
}
va_end(vaArgs);
if(lastline<buffer_lines-1)
{ lastline++;
}
// just zero end of buffer.....in case.
MainBuff[buffer_lines*max_length]=0;
LeaveCriticalSection(&cs);
}
/************************************************************************
* LastPrintBuffEpos *
* - Often we use PrintBuff followed by LastPrintBuff to construct a *
* line of output a piece at a time. This function provides basic *
* formatting by allowing us to set the cursor position on the last *
* line printed, by adding spaces until the position. *
************************************************************************/
// adds blanks to previous line to set position
void LastPrintBuffEpos(UINT xpos)
{ UINT i;
int spos;
EnterCriticalSection(&cs);
if(lastline)
{ spos=(lastline-1)*max_length;
i=strlen(&MainBuff[spos]);
while(i<xpos)
{ MainBuff[spos+i]=' ';
MainBuff[spos+i+1]=0;
i++;
}
}
LeaveCriticalSection(&cs);
}
/************************************************************************
* LastPrintBuffHexValue *
* - Same as LastPrintBuff, but prints num only, in hex. It prints a *
* leading zero where the leading char is alpha. *
************************************************************************/
void LastPrintBuffHexValue(byte num)
{ char tstr[20];
sprintf(tstr,"%02xh",num);
if((tstr[0]>='a')&&(tstr[0]<='f'))
LastPrintBuff("0");
LastPrintBuff("%02xh",num);
}
/************************************************************************
* LastPrintBuffHexValue *
* - Same as LastPrintBuff, but prints num only, in hex. It prints a *
* leading zero where the leading char is alpha. *
************************************************************************/
void LastPrintBuffLongHexValue(dword num)
{ char tstr[20];
sprintf(tstr,"%02lxh",num);
if((tstr[0]>='a')&&(tstr[0]<='f'))
LastPrintBuff("0");
LastPrintBuff("%02lxh",num);
}
/************************************************************************
* LastPrintBuff *
* - This is the same as PrintBuff except that instead of printing a new *
* line it goes back to the last line and adds more to the end of it *
* - So a set of calls tends to look like PrintBuff, LastPrintBuffEPos, *
* LastPrintBuff, LastPrintBuffEPos, LastPrintBuff, PrintBuff, etc *
************************************************************************/
void LastPrintBuff(char *szFormat,...)
{ int spos;
EnterCriticalSection(&cs);
va_list vaArgs;
va_start(vaArgs,szFormat);
if(lastline)
{ spos=(lastline-1)*max_length;
if(strlen(&MainBuff[spos])<max_length)
wvsprintf(&MainBuff[spos+strlen(&MainBuff[spos])],szFormat,vaArgs);
}
MainBuff[buffer_lines*max_length]=0;
va_end(vaArgs);
LeaveCriticalSection(&cs);
}
/************************************************************************
* DumpBuff *
* - Now this is a real hack. Instead of writing proper file IO routines *
* I simply write a buffer full at a time, and dump each to a file.... *
* Then when I've written the file out I regenerate the buffer for the *
* display again....... to be rewritten...... *
************************************************************************/
void DumpBuff(HANDLE efile)
{ dword num;
unsigned int i;
for(i=0;i<lastline;i++)
{ WriteFile(efile,&MainBuff[i*max_length],lstrlen(&MainBuff[i*max_length]),&num,NULL);
WriteFile(efile,"\r\n",2,&num,NULL);
}
}
/************************************************************************
* DoPaint *
* - This is the main painting routine. If the program is quitting then *
* it returns (we dont want thread clashes due to critical sections *
* here and theres no point to repainting when we're exitting). *
* - If the buffer is not ready then we wait, and go to sleep. *
* - Otherwise the routine paints the screen from the buffer, using the *
* selected font and colours *
************************************************************************/
void DoPaint(HWND hWnd,int cxChar,int cyChar)
{ HDC hDC; // handle for the display device
PAINTSTRUCT ps; // holds PAINT information
UINT nI;
RECT rRect;
int startpt,sn;
char sl[300];
cyc=cyChar;
while(!bufferready)
Sleep(0); // wait if filling buffer
if(KillThread)
return;
if(!lastline)
{ PaintBack(hWnd);
return;
}
EnterCriticalSection(&cs);
memset(&ps, 0x00, sizeof(PAINTSTRUCT));
hDC = BeginPaint(hWnd, &ps);
// Included as the background is not a pure color
//SetBkMode(hDC,TRANSPARENT);
switch(options.font)
{ case courierfont:
case courierfont10:
case courierfont12:
if(cf==NULL)
SelectObject(hDC,GetStockObject(ANSI_FIXED_FONT));
else
SelectObject(hDC,cf);
break;
case ansifont:
SelectObject(hDC,GetStockObject(ANSI_FIXED_FONT));
break;
case systemfont:
SelectObject(hDC,GetStockObject(SYSTEM_FIXED_FONT));
break;
default:
SelectObject(hDC,GetStockObject(ANSI_FIXED_FONT));
break;
}
GetClientRect(hWnd,&rRect);
if(hpos>max_length-(rRect.right/cxChar))
hpos=max_length-rRect.right/cxChar;
if(rrr!=(unsigned int)rRect.right)
{ rrr=(unsigned int)rRect.right;
SetScrollRange(hWnd,SB_HORZ,0,max_length-rRect.right/cxChar,true);
}
SetScrollPos(hWnd,SB_HORZ,hpos,true);
nScreenRows = rRect.bottom/cyChar;
ShowScrollBar (hWnd, SB_VERT, true);
ShowScrollBar (hWnd, SB_HORZ, max_length>(rRect.right/cxChar));
startpt=0;
SetTextColor(hDC,options.textcolor);
for(nI=startpt;nI<lastline;nI++)
{ if((userselonscreen)&&(nI==usersel))
SetBkColor(hDC,options.highcolor);
else
SetBkColor(hDC,options.bgcolor);
strcpy(sl,&MainBuff[nI*max_length]);
sn=strlen(sl);
memset(&sl[sn],' ',max_length-sn);
sl[max_length]=0;
TabbedTextOut(hDC,2-hpos*cxChar,nI*cyChar,sl,
max_length,0,NULL,2-hpos*cxChar);
}
for(nI=lastline;nI<nScreenRows+1;nI++)
{ if((userselonscreen)&&(nI==usersel))
SetBkColor(hDC,options.highcolor);
else
SetBkColor(hDC,options.bgcolor);
memset(sl,' ',max_length);
sl[max_length]=0;
TabbedTextOut(hDC,2-hpos*cxChar,nI*cyChar,sl,
max_length,0,NULL,2-hpos*cxChar);
}
// Inform Windows painting is complete
EndPaint(hWnd,&ps);
LeaveCriticalSection(&cs);
}
/************************************************************************
* PaintBack *
* - This is the routine for painting when there is no file loaded. It *
* simply paints the background in our selected colour. *
* - Yet another quick hack, from the above routine.... looks ok though *
************************************************************************/
void PaintBack(HWND hWnd)
{ HDC hDC; // handle for the display device
PAINTSTRUCT ps; // holds PAINT information
RECT rRect;
EnterCriticalSection(&cs);
memset(&ps, 0x00, sizeof(PAINTSTRUCT));
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd,&rRect);
ShowScrollBar (hWnd, SB_VERT, true);
FillRect(hDC, &rRect, (HBRUSH) CreateSolidBrush(options.bgcolor));
EndPaint(hWnd,&ps);
LeaveCriticalSection(&cs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -