(skip this first paragraph to get straight to the question) I have been attempting to augment my workflow in a little-known game engine for a game called "Natural Selection 2", and my plan is to be able to Ctrl+C from the level editor, run a script in Blender to import the data, then be able to run another script to export the modified data to the clipboard, then simply Ctrl+V back in the editor. This is MUCH faster than saving/loading a couple of files, and for the most part, I've got it working.
Anyways, I have code that works! Except in Blender, that is... sometimes... I'll explain below.
from ctypes import *
from binascii import *
from struct import *
from time import sleep
memcpy = cdll.msvcrt.memcpy
kernel32 = windll.kernel32
user32 = windll.user32
user32.OpenClipboard(None)
user32.EmptyClipboard()
CF_SPARK = user32.RegisterClipboardFormatW("application/spark editor")
GPTR = 0x0040
sampleString = b''
sampleString +=pack('L', 1)
sampleString +=pack('L', 268)
sampleString += b'sheetsmellssheetsmellsbythesheetstore'
hexlify(sampleString) ########### 1
length = len(sampleString)
memory_handle = kernel32.GlobalAlloc(GPTR,length)
error = kernel32.GetLastError()
print("error= ",error) ########## 2
data_point = kernel32.GlobalLock(memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 3
for i in range(0,length):
value = int.from_bytes((sampleString[i:i+1]), byteorder='little')
memset(data_point+i,value,1)
kernel32.GlobalUnlock(memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 4
user32.SetClipboardData(CF_SPARK,memory_handle)
error = kernel32.GetLastError()
print("error= ",error) ########## 5
user32.CloseClipboard()
print("finished")
See, this code runs perfectly fine from IDLE, even if I comment out all the lines with the ####### on them. But here's the thing... when running the script from BLENDER... those lines are CRITICAL. Why? I don't have a darn clue. They're just print statements, they should be completely inconsequential... right? But if I comment them out and run the script, 1 of 2 things happens: 1) The clipboard is just empty when the script finishes, or 2) I get an "access violation" for the memory location of 0x0000000000000000... which is DEFINITELY not where it's supposed to be looking. Does anybody know what could be causing this? I mean... the script works, and I guess I could just learn to live with this... but it really bothers me that it mysteriously fails under those conditions.
P.S. If anybody knows of a better way to do this, I'm all ears. But, any alternative solution MUST: 1) Be able to write BINARY data to the clipboard (not plain text... BINARY) 2) Work for Windows (don't care about Mac or Linux here, as the game's tools are Win-only. 3) Work without relying on null-terminated strings, as the data I'm copying over is full of nulls. Also, I would PREFER that the solution isn't difficult to install. Here, I've chosen ctypes because it's part of the standard library -- no extra packages needed! See, my hope is that I can release these scripts to the NS2 (natural selection 2) community and that would help people make better maps! Since I'm not the only one using it, I'll have to provide installation instructions, and I'll be damned if I'm going to walk people through the bajillion steps it takes to get pywin32 working in Blender (I couldn't).
Cheers! Thanks for reading! -Beige