Перейти к содержанию

[Asm] Как Сохранить


Рекомендуемые сообщения

Почему так работает:


;==============================================
format PE GUI 4.0
entry start
include 'win32ax.inc'
;==============================================

;==============================================
DM_BITSPERPEL = $40000;
DM_PELSWIDTH = $80000;
DM_PELSHEIGHT = $100000;
DM_DISPLAYFREQUENCY = $400000;
CDS_FULLSCREEN = $00000004;
DM_DISPLAYFLAGS = $200000;
;==============================================

;==============================================
struct DEVMODE
dmDeviceName db 32 dup (?)
dmSpecVersion dw ?
dmDriverVersion dw ?
dmSize dw ?
dmDriverExtra dw ?
dmFields dd ?
dmOrientation dw ?
dmPaperSize dw ?
dmPaperLength dw ?
dmPaperWidth dw ?
dmScale dw ?
dmCopies dw ?
dmDefaultSource dw ?
dmPrintQuality dw ?
dmColor dw ?
dmDuplex dw ?
dmYResolution dw ?
dmTTOption dw ?
dmCollate dw ?
dmFormName db 32 dup (?)
dmLogPixels dw ?
dmBitsPerPel dd ?
dmPelsWidth dd ?
dmPelsHeight dd ?
dmDisplayFlags dd ?
dmDisplayFrequency dd ?
dmICMMethod dd ?
dmICMIntent dd ?
dmMediaType dd ?
dmDitherType dd ?
dmReserved1 dd ?
dmReserved2 dd ?
ends
;==============================================

;==============================================
section '.data' data readable writable
dmScreenSettings DEVMODE
;==============================================

;==============================================
section '.text' code readable executable
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
or eax,eax
jz exit
exit:
invoke ExitProcess,0

proc DialogProc hwnddlg,msg,wparam,lparam
push ebx esi edi
cmp [msg],WM_CLOSE
je .wmclose
cmp [msg],WM_LBUTTONDOWN
je .move
cmp [msg],WM_RBUTTONUP
je .wmclose
cmp [msg],WM_INITDIALOG
je .init
cmp [msg],WM_TIMER
je .timer
xor eax,eax
jmp .finish

.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
jmp .processed
.wminitdialog:
jmp .processed
.wmcommand:
jmp .processed
.wmclose:
pop edi esi ebx
invoke EndDialog,[hwnddlg],0
.processed:
mov eax,1
ret
.init:
invoke SetTimer,[hwnddlg],0,100,0
ret
.timer:
invoke GetAsyncKeyState,VK_NUMPAD1
cmp eax,0
jne .func1ON
invoke GetAsyncKeyState,VK_NUMPAD0
cmp eax,0
jne .func1OFF
ret
.func1ON:
mov ecx,sizeof.DEVMODE
mov edi,dmScreenSettings
xor eax,eax
rep stosb
mov [dmScreenSettings.dmSize],sizeof.DEVMODE
mov [dmScreenSettings.dmPelsWidth],1280
mov [dmScreenSettings.dmPelsHeight],1024
mov [dmScreenSettings.dmDisplayFrequency],75
mov [dmScreenSettings.dmFields],DM_PELSWIDTH or DM_PELSHEIGHT or DM_DISPLAYFREQUENCY
push 1
push dmScreenSettings
call [ChangeDisplaySettings]
je .finish
.func1OFF:
mov ecx,sizeof.DEVMODE
mov edi,dmScreenSettings
xor eax,eax
rep stosb;
mov [dmScreenSettings.dmSize],sizeof.DEVMODE
mov [dmScreenSettings.dmPelsWidth],1680
mov [dmScreenSettings.dmPelsHeight],1050
mov [dmScreenSettings.dmFields],DM_PELSWIDTH or DM_PELSHEIGHT
push 1
push dmScreenSettings
call [ChangeDisplaySettings]
je .finish
.finish:
pop edi esi ebx
ret
endp
;==============================================

;==============================================
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL',\
gdi,'GDI32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess';,\
import user,\
DialogBoxParam,'DialogBoxParamA',\
SendMessage,'SendMessageA',\
EndDialog,'EndDialog',\
SetTimer, 'SetTimer',\
MessageBox, 'MessageBoxA',\
GetAsyncKeyState, 'GetAsyncKeyState',\
ChangeDisplaySettings,'ChangeDisplaySettingsA'
import gdi,\
Rectangle,'Rectangle'
;==============================================

;==============================================
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'CS 1.6 accelerator',70,70,100,70,WS_POPUP
dialogitem 'STATIC','NumPad1 = Accelerate game',-1,3,0,100,188,WS_VISIBLE
dialogitem 'STATIC','NumPad0 = Reset to default',-2,3,10,100,15,WS_VISIBLE
enddialog
;==============================================

А так нет:


;==============================================
format PE GUI 4.0
entry start
include 'win32ax.inc'
;==============================================
;==============================================
DM_BITSPERPEL = $40000;
DM_PELSWIDTH = $80000;
DM_PELSHEIGHT = $100000;
DM_DISPLAYFREQUENCY = $400000;
CDS_FULLSCREEN = $00000004;
DM_DISPLAYFLAGS = $200000;
;==============================================
;==============================================
struct DEVMODE
dmDeviceName db 32 dup (?)
dmSpecVersion dw ?
dmDriverVersion dw ?
dmSize dw ?
dmDriverExtra dw ?
dmFields dd ?
dmOrientation dw ?
dmPaperSize dw ?
dmPaperLength dw ?
dmPaperWidth dw ?
dmScale dw ?
dmCopies dw ?
dmDefaultSource dw ?
dmPrintQuality dw ?
dmColor dw ?
dmDuplex dw ?
dmYResolution dw ?
dmTTOption dw ?
dmCollate dw ?
dmFormName db 32 dup (?)
dmLogPixels dw ?
dmBitsPerPel dd ?
dmPelsWidth dd ?
dmPelsHeight dd ?
dmDisplayFlags dd ?
dmDisplayFrequency dd ?
dmICMMethod dd ?
dmICMIntent dd ?
dmMediaType dd ?
dmDitherType dd ?
dmReserved1 dd ?
dmReserved2 dd ?
ends
;==============================================
;==============================================
section '.data' data readable writable
PelsWidth dd ?
PelsHeight dd ?
DisplayFrequency dd ?
dmScreenSettings DEVMODE
;==============================================
;==============================================
section '.text' code readable executable
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
or eax,eax
jz exit
exit:
invoke ExitProcess,0

proc DialogProc hwnddlg,msg,wparam,lparam
push ebx esi edi
cmp [msg],WM_CLOSE
je .wmclose
cmp [msg],WM_LBUTTONDOWN
je .move
cmp [msg],WM_RBUTTONUP
je .wmclose
cmp [msg],WM_INITDIALOG
je .init
cmp [msg],WM_TIMER
je .timer
xor eax,eax
jmp .finish

.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
jmp .processed
.wminitdialog:
jmp .processed
.wmcommand:
jmp .processed
.wmclose:
pop edi esi ebx
invoke EndDialog,[hwnddlg],0
.processed:
mov eax,1
ret
.init:
invoke SetTimer,[hwnddlg],0,100,0
ret
.timer:
invoke GetAsyncKeyState,VK_NUMPAD1
cmp eax,0
jne .func1ON
invoke GetAsyncKeyState,VK_NUMPAD0
cmp eax,0
jne .func1OFF
ret
.func1ON:
mov ecx,sizeof.DEVMODE
mov edi,dmScreenSettings
xor eax,eax
rep stosb
mov PelsWidth,dmScreenSettings.dmPelsWidth
mov PelsHeight,dmScreenSettings.dmPelsHeight
mov DisplayFrequency,dmScreenSettings.dmDisplayFrequency
mov [dmScreenSettings.dmSize],sizeof.DEVMODE
mov [dmScreenSettings.dmPelsWidth],1280
mov [dmScreenSettings.dmPelsHeight],1024
mov [dmScreenSettings.dmDisplayFrequency],75
mov [dmScreenSettings.dmFields],DM_PELSWIDTH or DM_PELSHEIGHT or DM_DISPLAYFREQUENCY
push 1
push dmScreenSettings
call [ChangeDisplaySettings]
je .finish
.func1OFF:
mov ecx,sizeof.DEVMODE
mov edi,dmScreenSettings
xor eax,eax
rep stosb;
mov [dmScreenSettings.dmSize],sizeof.DEVMODE
mov [dmScreenSettings.dmPelsWidth],PelsWidth
mov [dmScreenSettings.dmPelsHeight],PelsHeight
mov [dmScreenSettings.dmFields],DM_PELSWIDTH or DM_PELSHEIGHT
push 1
push dmScreenSettings
call [ChangeDisplaySettings]
je .finish
.finish:
pop edi esi ebx
ret
endp
;==============================================
;==============================================
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL',\
gdi,'GDI32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess';,\
import user,\
DialogBoxParam,'DialogBoxParamA',\
SendMessage,'SendMessageA',\
EndDialog,'EndDialog',\
SetTimer, 'SetTimer',\
MessageBox, 'MessageBoxA',\
GetAsyncKeyState, 'GetAsyncKeyState',\
ChangeDisplaySettings,'ChangeDisplaySettingsA'
import gdi,\
Rectangle,'Rectangle'
;==============================================
;==============================================
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'CS 1.6 accelerator',70,70,100,70,WS_POPUP
dialogitem 'STATIC','NumPad1 = Accelerate game',-1,3,0,100,188,WS_VISIBLE
dialogitem 'STATIC','NumPad0 = Reset to default',-2,3,10,100,15,WS_VISIBLE
enddialog
;==============================================

???

Жаль в теге {code}{/code} нельзя выделять жирным текст, но в компиляторе сразу будет понятно где ошибка. В первом варианте func1ON меняет разрешение на 1280x1024, а func1OFF меняет на 1680x1050. А надо чтоб func1ON в самом начале создавала переменные и записывала туда текущее разрешение экрана, а func1OFF читала и применяла записанное в func1ON разрешение

Да ёмаё. Забыл тему сменить. Модеры переименуйте пожалуйста на "[ASM] Не получается записать значение в переменную" ну или что-то вроде того :)

Ссылка на комментарий
Поделиться на другие сайты

Так во втором варианте у тебя прога всё равно по таймеру ждёт нажатия клавиши. Вызывай, например, вот [это] (или даже вот [это] ) в wminitdialog, оно тебе с нужным флагом выплюнет текущее разрешение экрана - затем уже заполнишь нужную структуру и второй функцией установишь это разрешение.

А так, у тебя что в первом исходнике:

.timer:
invoke GetAsyncKeyState,VK_NUMPAD1
cmp eax,0
jne .func1ON
invoke GetAsyncKeyState,VK_NUMPAD0
cmp eax,0
jne .func1OFF
ret

Что во втором.

Ссылка на комментарий
Поделиться на другие сайты

А так, у тебя что в первом исходнике:

.timer:
invoke GetAsyncKeyState,VK_NUMPAD1
cmp eax,0
jne .func1ON
invoke GetAsyncKeyState,VK_NUMPAD0
cmp eax,0
jne .func1OFF
ret

Что во втором.

Различие в самих функциях (метках) func1ON и func1OFF. Вопрос всё тот же - почему выдаёт ошибку? Тип переменной правильный указал - dd

Так во втором варианте у тебя прога всё равно по таймеру ждёт нажатия клавиши

Она и должна ждать нажатия клавиши. По нажатию numpad1 должно: 1) Сохраняться текущее разрешение 2) Устанавливаться 1280x1024, По нажатию numpad2 должно восстанавливаться прежнее разрешение Изменено пользователем sooqua
Ссылка на комментарий
Поделиться на другие сайты

А, вроде нашёл.


mov PelsWidth,dmScreenSettings.dmPelsWidth
mov PelsHeight,dmScreenSettings.dmPelsHeight
mov DisplayFrequency,dmScreenSettings.dmDisplayFrequency

Этими строчками ты копируешь в переменные адреса полей структуры, а тебе надо их содержимое копировать. Попробуй:


mov PelsWidth,[dmScreenSettings.dmPelsWidth]

Например.

На какую строчку компилятор ругается и что пишет?

Ссылка на комментарий
Поделиться на другие сайты

А, вроде нашёл.


mov PelsWidth,dmScreenSettings.dmPelsWidth
mov PelsHeight,dmScreenSettings.dmPelsHeight
mov DisplayFrequency,dmScreenSettings.dmDisplayFrequency

Если конечно не трудно, лучше попробуй сам скомпилировать, понятнее всё будет, т.к. первая ошибка возникает немного выше....

На какую строчку компилятор ругается и что пишет?

mov PelsWidth,[dmScreenSettings.dmPelsWidth]

error: invalid operand.

Изменено пользователем sooqua
Ссылка на комментарий
Поделиться на другие сайты

Всё оказалось проще.

1. В секции данных объявляем структуру DEVMODE:

devsettings DEVMODE

2. В инициализации диалога делаем:

invoke  EnumDisplaySettings,0,-1,devsettings

0 - текущий видеоадаптер, к которому подцеплен основной поток вызывающего приложения, -1 - флаг ENUM_CURRENT_SETTINGS.

3. В таймере делаем:

invoke  ChangeDisplaySettings,devsettings,0

devsettings - заполненная ранее структура, 0 - от балды, не помню что именно этот флаг делает.

PS: Мне всё ещё любопытно, зачем ты с этим так мучаешься - уже, вроде, довольно долго.

Ссылка на комментарий
Поделиться на другие сайты

Всё оказалось проще.

1. В секции данных объявляем структуру DEVMODE:

devsettings DEVMODE

2. В инициализации диалога делаем:

invoke  EnumDisplaySettings,0,-1,devsettings

0 - текущий видеоадаптер, к которому подцеплен основной поток вызывающего приложения, -1 - флаг ENUM_CURRENT_SETTINGS.

3. В таймере делаем:

invoke  ChangeDisplaySettings,devsettings,0

devsettings - заполненная ранее структура, 0 - от балды, не помню что именно этот флаг делает.

PS: Мне всё ещё любопытно, зачем ты с этим так мучаешься - уже, вроде, довольно долго.

Не давно)))) Я в тот день же и забил, просто сегодня решил немного усовершенствовать)))) Спасибо, попробуем щас
Ссылка на комментарий
Поделиться на другие сайты

Создал структуру:

struct DisplayStruct
Width dd ?
Height dd ?
Frequency dd ?
ends

Что-то с ней сделал :D (повторил за: dmScreenSettings DEVMODE):

DisplaySettings DisplayStruct

Пишу:

mov [DisplaySettings.Width],[dmScreenSettings.dmPelsWidth]

Он мне ту же ошибку:

mov [DisplaySettings.Width],[dmScreenSettings.dmPelsWidth]

error: invalid operand.

Ссылка на комментарий
Поделиться на другие сайты

Дык зачем? Создай пустую DEVMODE, которая у тебя и так объявлена. В initdialog вызываешь одну функцию, которая её заполняет структуру текущими настройками, затем её (уже заполненную) используешь для смены видеорежима. Ничего менять не надо.


section '.data' data readable writable
devsettings DEVMODE

...

.wminitdialog:
invoke EnumDisplaySettings,0,-1,devsettings //Читаем текущий видеорежим
invoke SetTimer,[hwnddlg],0,100,0
jmp .processed
.timer:
invoke GetAsyncKeyState,VK_F1
cmp eax,0
jne .f1
jmp .processed
.f1:
invoke Beep,1000,500
invoke ChangeDisplaySettings,devsettings,0 //При нажатии кнопки - восстанавливаем ранее прочитанный
jmp .processed
.move:
invoke SendMessage,[hwnddlg],0xA1,0x2,0
jmp .processed

Ссылка на комментарий
Поделиться на другие сайты

Ну так это WinAPI-функция. Скорее всего, ты её не объявил:


import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess',\
Beep,'Beep'

import user,\
DialogBoxParam,'DialogBoxParamA',\
EndDialog,'EndDialog',\
SendMessage,'SendMessageA',\
SetTimer,'SetTimer',\
GetAsyncKeyState, 'GetAsyncKeyState',\
EnumDisplaySettings,'EnumDisplaySettingsA',\
ChangeDisplaySettings,'ChangeDisplaySettingsA'

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.