![]() |
Platforms, Frameworks & Libraries »
Win32/64 SDK & OS »
General
Intermediate
License: The Code Project Open License (CPOL)
An extendable report editorBy RockmanZeroan extendable report editor |
C++ (VC6, VC7, VC7.1, VC8.0), C++/CLI, C
|
||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Create a report or create a dialog is normal part of most applications, but far too convoluted for many developers. If you are a Microsoft Visual Studio user, you are very lucky, you can drag controls from the controls pad to your dialog, and the code is created at the same time.But how about other platforms? How about generating the code for your own controls? we can only say sorry, you must write all the code by your hand. Here, I come to the aid, with this extendable workshop, you can simply add your own contorls without recomplie the program or write any annoying plugins.
use c++ as your script language is a good idea, but it's really a difficult thing, because c++ syntax is too complex to implement. There are many good c++ complier in this world , VC++6.0 is what I most common use. My idea is first use c++ complier to change .c or .cpp source into .asm file, then use a assembler to convert .asm file to binary file.you can load this binary file into your program and let it run on a small virtual machine. This program inlude a small virtual machine that can execute many i386 instructions.
(1) C++ script language supported.
(2) Full mouse
handling. Draw and drag multiple objects, and resize multiple ones.
(3) Snap
to grid.
(4) Group or Ungroup multiple objects.
(5) Easy to Extend,
without recomplie or plugins.
Add your own controls is an easy thing, you don't need to re-complie it, the only thing you need is a text editor, notpad is OK, but I strongly recommend use an XML editor, I use XmlBluePrint, that is a very good XML editor, you can visit http://www.xmlblueprint.com/ to get one.
<Test isnode="true">
<code>
<![CDATA[
//your can add your global variables here
int global;
int code(int code_num)
{
//when you click 'code' button on tool bar, this function will be called.
//this function will be called 10 times, code_num equals number of times.
printf("test code");
return OK;
}
int before_draw()
{
//this function will be called before draw all contorls
return OK;
}
int draw()
{
//how to draw this contorl.
return OK;
}
]]>
</code>
<default>
<![CDATA[
//code here will be put into _init_attrib() function
global = 100;
]]>
</default>
</Test>
A single control node must be put under AllNode.
Be sure isnode="true" is must or you will not see this node in the tree view.
When you finish a node,save the xml file then open this program again, you will see a new node in the tree view.
Virtual machine is a software computer in my understanding, it can be very simple or very complex, a complex virtual machine can let morden OS like Windows or Linux run on it, a simple virtual machine can only contains a simple soft CPU and simple soft memory. The virtual machine in this program belongs to the latter.
A program can be viewed as a serial of instructions and what does CPU do is just fetch next instruction and interpret it, so a typical skeleton of CPU emulator in C++ is
this->vm->LoadFile(pobj->mf_bin); //Load binary image
//run it
while(!this->vm->end_flag)
{
this->vm->GetNextOper();
this->vm->ExeOper();
}
ExeOper() is used to interpret each instruction, follow is the source code.
int CVm::ExeOper()
{
int oper = *((WORD*)(this->cur_oper));
switch(oper)
{
case OPER_ADC:do_adc();break;
case OPER_ADD:do_add();break;
case OPER_AND:do_and();break;
case OPER_CALL:do_call();break;
case OPER_CDQ:do_cdq();break;
case OPER_CMP:do_cmp();break;
case OPER_CMPSB:do_cmpsb();break;
case OPER_CMPSD:do_cmpsd();break;
case OPER_CMPSW:do_cmpsw();break;
case OPER_DEC:do_dec();break;
case OPER_DIV:do_div();break;
case OPER_FADD:do_fadd();break;
case OPER_FCOS:do_fcos();break;
case OPER_FILD:do_fild();break;
case OPER_FLD:do_fld();break;
case OPER_FMUL:do_fmul();break;
case OPER_FSIN:do_fsin();break;
case OPER_FST:do_fst();break;
case OPER_FSTP:do_fstp();break;
case OPER_FSUB:do_fsub();break;
case OPER_FXCH:do_fxch();break;
case OPER_IDIV:do_idiv();break;
case OPER_IMUL:do_imul();break;
case OPER_INC:do_inc();break;
case OPER_INT:do_int();break;
case OPER_JA:do_ja();break;
case OPER_JB:do_jb();break;
case OPER_JBE:do_jbe();break;
case OPER_JE:do_je();break;
case OPER_JG:do_jg();break;
case OPER_JGE:do_jge();break;
case OPER_JL:do_jl();break;
case OPER_JLE:do_jle();break;
case OPER_JMP:do_jmp();break;
case OPER_JNE:do_jne();break;
case OPER_JNS:do_jns();break;
case OPER_JS:do_js();break;
case OPER_LEA:do_lea();break;
case OPER_MOV:do_mov();break;
case OPER_MOVSB:do_movsb();break;
case OPER_MOVSD:do_movsd();break;
case OPER_MOVSW:do_movsw();break;
case OPER_MOVSX:do_movsx();break;
case OPER_MUL:do_mul();break;
case OPER_MYADD:do_myadd();break;
case OPER_MYDIV:do_mydiv();break;
case OPER_MYMUL:do_mymul();break;
case OPER_MYSUB:do_mysub();break;
case OPER_NEG:do_neg();break;
case OPER_NOT:do_not();break;
case OPER_NPAD:do_npad();break;
case OPER_OR:do_or();break;
case OPER_POP:do_pop();break;
case OPER_PUSH:do_push();break;
case OPER_REP:do_rep();break;
case OPER_REPNE:do_repne();break;
case OPER_RET:do_ret();break;
case OPER_SAR:do_sar();break;
case OPER_SBB:do_sbb();break;
case OPER_SCASB:do_scasb();break;
case OPER_SCASD:do_scasd();break;
case OPER_SCASW:do_scasw();break;
case OPER_SETE:do_sete();break;
case OPER_SETG:do_setg();break;
case OPER_SETGE:do_setge();break;
case OPER_SETL:do_setl();break;
case OPER_SETLE:do_setle();break;
case OPER_SETNE:do_setne();break;
case OPER_SHL:do_shl();break;
case OPER_SHR:do_shr();break;
case OPER_STOSB:do_stosb();break;
case OPER_STOSD:do_stosd();break;
case OPER_STOSW:do_stosw();break;
case OPER_SUB:do_sub();break;
case OPER_TEST:do_test();break;
case OPER_XOR:do_xor();break;
case OPER_JAE:do_jae();break;
case OPER_FSUBR:do_fsubr();break;
case OPER_FDIV:do_fdiv();break;
case OPER_FADDP:do_faddp();break;
case OPER_FDIVR:do_fdivr();break;
case OPER_FIADD:do_fiadd();break;
case OPER_FMULP:do_fmulp();break;
case OPER_FSUBP:do_fsubp();break;
case OPER_FISUB:do_fisub();break;
case OPER_FISUBR:do_fisubr();break;
case OPER_FIMUL:do_fimul();break;
case OPER_FSUBRP:do_fsubrp();break;
case OPER_FCHS:do_fchs();break;
case OPER_FABS:do_fabs();break;
case OPER_FDIVP:do_fdivp();break;
case OPER_FIDIV:do_fidiv();break;
case OPER_FIDIVR:do_fidivr();break;
case OPER_FDIVRP:do_fdivrp();break;
case OPER_WAIT:do_wait();break;
case OPER_LEAVE:do_leave();break;
case OPER_FNSTCW:do_fnstcw();break;
case OPER_FLDCW:do_fldcw();break;
case OPER_FISTP:do_fistp();break;
case OPER_FCOMP:do_fcomp();break;
case OPER_FCOM:do_fcom();break;
case OPER_FIST:do_fist();break;
case OPER_FNSTSW:do_fnstsw();break;
case OPER_FSTSW:do_fstsw();break;
case OPER_FPTAN:do_fptan();break;
case OPER_FPATAN:do_fpatan();break;
case OPER_FSQRT:do_fsqrt();break;
case OPER_FLD1:do_fld1();break;
case OPER_FLDZ:do_fldz();break;
case OPER_FLDPI:do_fldpi();break;
case OPER_FLDL2E:do_fldl2e();break;
case OPER_FLDL2T:do_fldl2t();break;
case OPER_FLDLG2:do_fldlg2();break;
case OPER_FLDLN2:do_fldln2();break;
case OPER_FRNDINT:do_frndint();break;
case OPER_FSCALE:do_fscale();break;
case OPER_F2XM1:do_f2xm1();break;
case OPER_LAHF:do_lahf();break;
case OPER_SAHF:do_sahf();break;
case OPER_FYL2X:do_fyl2x();break;
case OPER_FXAM:do_fxam();break;
case OPER_FCLEX:do_fclex();break;
case OPER_JZ:do_jz();break;
case OPER_FPREM:do_fprem();break;
case OPER_JNZ:do_jnz();break;
case OPER_FSTCW:do_fstcw();break;
case OPER_FTST:do_ftst();break;
case OPER_FXTRACT:do_fxtract();break;
case OPER_REPE:do_repe();break;
default: this->runtime_error("error oper %d\n",oper);break;
}
return OK;
}
An important question is how the virtual machine communicate with host. Host can access the registers of virtual machine CPU and can read or write virtual memory directly, because host handle all the data of virtual machine. Virtual machine can not access host directly, that can cause big safe problems, so I use "int" instruction for communicate with the host. CVm::do_int() is a virtual member function, so that the derived class can change it easily.
CMyVM::do_int()
{
int int_num;
_RegVal val;
this->GetOpnd1(&val); //get the first opnd, it is INT number
int_num = val.val_32;
switch(int_num)
{
case 0: this->end_flag = true; break; //exit
case 1: this->do_int_1();break;
case 2: this->do_int_2();break;
case 3: this->do_int_3();break;
......
}
return OK;
}
the parameters can pass via registers or stack,if all the parameters are 4 bytes the virtual address of parameter can be simply get by expression esp + 4*i + 4
DWORD CMyVM::GetParam(int i)
{
long esp = this->reg_index[REG_ESP]->val.val_32;
return this->i_vmem->Read32Mem(esp + 4*i + 4);
}
an example
int CMyVM::do_int_2()
{
//set_pixel(int x,int y,COLORREF color)
this->i_canvas->SetPixel(this->GetParam(0),this->GetParam(1),this->GetParam(2));
return OK;
}
just declared at host side is not the end, you still can't use at virtual machine side, you must declare it at virtual machine side. the function is written by assemble language
_set_pixel proc
int 2
ret
_set_pixel endp
and must be declared in .h file
int set_pixel(int x,int y,COLORREF color);
In _bootloader.asm in Workshop.xml some ret instructions are forgotten. this may cause unwanted execution sequence.
_get_cookie_size proc
_read_cookie proc
_write_cookie proc
_set_font proc
use a text editor to open workshop.xml add ret at the end of each proc.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+PgUp/PgDown to switch pages.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 3 Sep 2008 Editor: |
Copyright 2008 by RockmanZero Everything else Copyright © CodeProject, 1999-2010 Web10 | Advertise on the Code Project |